<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Polling_model extends CI_Model {

    protected $table_polling = 'polling';
    protected $table_votes   = 'polling_votes';

    public function __construct() {
        parent::__construct();
    }

    // ─────────────────────────────────────────────────────────
    //  POLLING CRUD
    // ─────────────────────────────────────────────────────────

    /**
     * Ambil semua polling, optional filter status.
     * Otomatis hitung total_suara dari opsi_json.
     */
    public function get_all($status = null) {
        if ($status) {
            $this->db->where($this->table_polling . '.status', $status);
        }
        $rows = $this->db
            ->order_by($this->table_polling . '.created_at', 'DESC')
            ->get($this->table_polling)
            ->result();

        // Hitung total_suara dari opsi_json
        foreach ($rows as &$row) {
            $opsi = json_decode($row->opsi_json, true) ?? [];
            $row->total_suara = array_sum(array_column($opsi, 'suara'));
        }
        unset($row);

        return $rows;
    }

    /**
     * Ambil satu polling berdasarkan ID.
     */
    public function get_by_id($id) {
        return $this->db
            ->where('id', (int)$id)
            ->get($this->table_polling)
            ->row();
    }

    /**
     * Hitung jumlah polling berdasarkan status.
     */
    public function count_status($status) {
        return $this->db
            ->where('status', $status)
            ->count_all_results($this->table_polling);
    }

    /**
     * Insert polling baru. Return insert_id.
     */
    public function insert($data) {
        $this->db->insert($this->table_polling, $data);
        return $this->db->insert_id();
    }

    /**
     * Update data polling berdasarkan ID.
     */
    public function update($id, $data) {
        $this->db
            ->where('id', (int)$id)
            ->update($this->table_polling, $data);
        return $this->db->affected_rows();
    }

    /**
     * Update hanya kolom opsi_json (digunakan saat vote).
     */
    public function update_opsi($id, $opsi_json) {
        $this->db
            ->where('id', (int)$id)
            ->update($this->table_polling, ['opsi_json' => $opsi_json]);
        return $this->db->affected_rows();
    }

    /**
     * Hapus polling. Votes terhapus otomatis jika ada FK CASCADE,
     * atau dihapus manual di sini.
     */
    public function delete($id) {
        // Hapus semua votes dulu (jika tidak pakai FK cascade)
        $this->db->where('polling_id', (int)$id)->delete($this->table_votes);

        // Hapus polling
        $this->db->where('id', (int)$id)->delete($this->table_polling);

        return $this->db->affected_rows();
    }

    // ─────────────────────────────────────────────────────────
    //  VOTES
    // ─────────────────────────────────────────────────────────

    /**
     * Cek apakah user sudah vote di polling tertentu.
     * Return: object row atau NULL.
     */
    public function get_user_vote($polling_id, $user_id) {
        return $this->db
            ->where('polling_id', (int)$polling_id)
            ->where('user_id',   (int)$user_id)
            ->get($this->table_votes)
            ->row();
    }

    /**
     * Ambil semua voter dari sebuah polling.
     * Return: array of objects.
     */
    public function get_voters($polling_id) {
        return $this->db
            ->where('polling_id', (int)$polling_id)
            ->order_by('created_at', 'ASC')
            ->get($this->table_votes)
            ->result();
    }

    /**
     * Hitung jumlah voter di sebuah polling.
     */
    public function count_voters($polling_id) {
        return $this->db
            ->where('polling_id', (int)$polling_id)
            ->count_all_results($this->table_votes);
    }

    /**
     * Insert record vote baru.
     */
    public function insert_vote($data) {
        $this->db->insert($this->table_votes, $data);
        return $this->db->insert_id();
    }

    /**
     * Update pilihan pada record vote yang sudah ada (ganti suara).
     */
    public function update_vote($vote_id, $pilihan_baru) {
        $this->db
            ->where('id', (int)$vote_id)
            ->update($this->table_votes, [
                'pilihan'    => $pilihan_baru,
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
        return $this->db->affected_rows();
    }

    /**
     * Hapus semua votes dari polling tertentu (untuk reset).
     */
    public function delete_votes($polling_id) {
        $this->db->where('polling_id', (int)$polling_id)->delete($this->table_votes);
        return $this->db->affected_rows();
    }

    // ─────────────────────────────────────────────────────────
    //  STATISTIK (opsional, untuk dashboard)
    // ─────────────────────────────────────────────────────────

    /**
     * Ambil polling aktif terbaru (untuk widget dashboard).
     */
    public function get_aktif_terbaru($limit = 3) {
        return $this->db
            ->where('status', 'aktif')
            ->order_by('created_at', 'DESC')
            ->limit($limit)
            ->get($this->table_polling)
            ->result();
    }

    /**
     * Total polling yang pernah dibuat.
     */
    public function count_all() {
        return $this->db->count_all($this->table_polling);
    }

    /**
     * Total suara dari semua polling (agregat).
     */
    public function total_suara_semua() {
        $result = $this->db
            ->select_sum('jumlah_suara')
            ->get($this->table_votes)
            ->row();
        return $result->jumlah_suara ?? 0;
    }

}