<?php

namespace App\Models;

use CodeIgniter\Model;

class SoalModel extends Model
{
    protected $table            = 'soal';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = false;
    protected $allowedFields    = [
        'id',
        'bank_soal_id',
        'soal_no',
        'jenis_soal',
        'pertanyaan',
        'jawaban',
        'topik_soal_id',
        'bobot',

        'created_at',
        'updated_at'
    ];
    protected $useTimestamps = false;

    // Optional: jika ingin menambahkan relasi ke soal_opsi
    public function withOpsi($soalId)
    {
        return $this->db->table('soal')
            ->select('soal.*, soal_opsi.id as opsi_id, soal_opsi.teks, soal_opsi.label, soal_opsi.is_true, soal_opsi.bobot as opsi_bobot')
            ->join('soal_opsi', 'soal_opsi.soal_id = soal.id', 'left')
            ->where('soal.id', $soalId)
            ->get()
            ->getResultArray();
    }
    public function getSoalByBank($bankSoalId, $acakSoal = false, $acakOpsi = false)
    {
        // Ambil data soal dengan topik
        $soalList = $this->db->table('soal s')
            ->select('s.*, ts.nama as nama_topik')
            ->join('topik_soal ts', 'ts.id = s.topik_soal_id', 'left')
            ->where('s.bank_soal_id', $bankSoalId)
            ->orderBy('s.soal_no', 'ASC')
            ->get()
            ->getResultArray();

        if (empty($soalList)) {
            return [];
        }

        // Acak soal jika perlu
        if ($acakSoal) {
            shuffle($soalList);
        }

        $soalIds = array_column($soalList, 'id');

        // Ambil opsi
        $opsiList = $this->db->table('soal_opsi')
            ->whereIn('soal_id', $soalIds)
            ->get()
            ->getResultArray();

        // Kelompokkan opsi per soal
        $groupedOpsi = [];
        foreach ($opsiList as $opsi) {
            $groupedOpsi[$opsi['soal_id']][] = $opsi;
        }

        // Gabungkan ke soal
        foreach ($soalList as &$soal) {
            $opsi = $groupedOpsi[$soal['id']] ?? [];
            if ($acakOpsi) {
                shuffle($opsi);
            }
            $soal['opsi'] = $opsi;
        }

        return $soalList;
    }


    public function getSoalIdsByBank($bankSoalId)
    {
        $soal = $this->select('id')
            ->where('bank_soal_id', $bankSoalId)
            ->orderBy('created_at', 'ASC')
            ->findAll();

        return array_column($soal, 'id'); // hanya array of ID
    }

    // Mapping acakan opsi
    public function getOpsiOrderMap($bankSoalId, $acak = false)
    {
        $soalList = $this->select('id')->where('bank_soal_id', $bankSoalId)->findAll();
        $result = [];

        foreach ($soalList as $soal) {
            $opsi = $this->db->table('soal_opsi')
                ->select('id')
                ->where('soal_id', $soal['id'])
                ->get()->getResultArray();

            $ids = array_column($opsi, 'id');
            if ($acak) {
                shuffle($ids);
            }

            $result[$soal['id']] = $ids;
        }

        return $result;
    }

    // Ambil soal dan opsi sesuai urutan
    public function getSoalByUrutan(array $soalIds, array $urutanOpsi)
    {
        if (empty($soalIds)) return [];

        // Escape dan format untuk FIELD()
        $escapedSoalIds = implode(',', array_map(function ($id) {
            return $this->db->escape($id);
        }, $soalIds));

        $soals = $this->db->table('soal')
            ->select('id, bank_soal_id,soal_no,jenis_soal,pertanyaan, created_at, updated_at')
            ->whereIn('id', $soalIds)
            ->orderBy("FIELD(id, {$escapedSoalIds})", '', false)
            ->get()->getResultArray();

        foreach ($soals as &$soal) {
            $opsiIds = $urutanOpsi[$soal['id']] ?? [];

            if (empty($opsiIds)) {
                $soal['opsi'] = [];
                continue;
            }

            $escapedOpsiIds = implode(',', array_map(function ($id) {
                return $this->db->escape($id);
            }, $opsiIds));

            $opsi = $this->db->table('soal_opsi')
                ->select('id, soal_id, label, teks, pasangan, created_at, updated_at')
                ->where('soal_id', $soal['id'])
                ->whereIn('id', $opsiIds)
                ->orderBy("FIELD(id, {$escapedOpsiIds})", '', false)
                ->get()->getResultArray();

            $soal['opsi'] = $opsi;
        }

        return $soals;
    }
    public function getSoalWithOpsi($bankSoalId)
    {
        $soalList = $this->where('bank_soal_id', $bankSoalId)
            ->orderBy('soal_no', 'ASC')
            ->findAll();

        $soalIds = array_column($soalList, 'id');

        if (empty($soalIds)) return [];

        // Ambil semua opsi sekaligus
        $opsiList = $this->db->table('soal_opsi')
            ->whereIn('soal_id', $soalIds)
            ->get()
            ->getResultArray();

        // Kelompokkan opsi berdasarkan soal_id
        $opsiGrouped = [];
        foreach ($opsiList as $opsi) {
            $opsiGrouped[$opsi['soal_id']][] = $opsi;
        }

        // Gabungkan ke soal
        foreach ($soalList as &$soal) {
            $soal['opsi'] = $opsiGrouped[$soal['id']] ?? [];
        }

        return $soalList;
    }
}
