<?php

namespace App\Models;

use CodeIgniter\Model;

class LaporanModel extends Model
{
    protected $table = 'peminjaman';
    protected $primaryKey = 'id';
    protected $returnType = 'array';

    /**
     * Laporan seluruh peminjaman
     */
    public function getLaporanSiswa($tglAwal = null, $tglAkhir = null)
    {
        $builder = $this->db->table('anggota a');

        $builder->select('
            a.id as anggota_id,
            a.nisn,
            a.nama,
            a.jenis,
            a.kelas,
            COUNT(p.id) as total_pinjam,
            SUM(CASE WHEN p.status = "Dikembalikan" THEN 1 ELSE 0 END) as sudah_kembali,
            SUM(CASE WHEN p.status = "Dipinjam" THEN 1 ELSE 0 END) as belum_kembali,
            SUM(COALESCE(p.denda, 0)) as total_denda
        ');

        $builder->join('peminjaman p', 'p.anggota_id = a.id', 'left');

        if ($tglAwal != null && $tglAkhir != null) {
            $builder->where('p.tanggal_pinjam >=', $tglAwal);
            $builder->where('p.tanggal_pinjam <=', $tglAkhir);
        }

        $builder->groupBy('a.id');
        $builder->orderBy('a.nama', 'ASC');

        return $builder->get()->getResultArray();
    }

    /**
     * Detail laporan berdasarkan anggota
     */
    public function getDetailSiswa($anggota_id)
    {
        return $this->db->table('peminjaman p')
            ->select("
                p.*,
                a.id as anggota_id,
                a.nama,
                a.nisn,
                a.kelas,
                b.judul,
                b.kode_buku,
                pk.tanggal_kembali_real as tanggal_dikembalikan,
                COALESCE(pk.hari_terlambat,
                    GREATEST(
                        DATEDIFF(CURDATE(), p.tanggal_kembali),
                        0
                    ), 0
                ) as hari_terlambat
            ")
            ->join('anggota a', 'a.id=p.anggota_id')
            ->join('buku b', 'b.id=p.buku_id')
            ->join('pengembalian pk', 'pk.kode_pinjam = p.kode_pinjam', 'left')
            ->where('p.anggota_id', $anggota_id)
            ->orderBy('p.tanggal_pinjam', 'DESC')
            ->get()
            ->getResultArray();
    }

    /**
     * Total peminjaman
     */
    public function totalPeminjaman()
    {
        return $this->db->table('peminjaman')->countAllResults();
    }

    /**
     * Total pengembalian
     */
    public function totalPengembalian()
    {
        return $this->db->table('peminjaman')
            ->where('status', 'Dikembalikan')
            ->countAllResults();
    }

    /**
     * Total belum kembali
     */
    public function totalBelumKembali()
    {
        return $this->db->table('peminjaman')
            ->where('status', 'Dipinjam')
            ->countAllResults();
    }

    /**
     * Total denda
     */
    public function totalDenda()
    {
        return $this->db->table('peminjaman')
            ->selectSum('denda')
            ->get()
            ->getRow()
            ->denda ?? 0;
    }

    /**
     * Alias total denda
     */
    public function getTotalDenda($anggota_id = null)
    {
        if ($anggota_id) {
            return $this->db->table('peminjaman')
                ->where('anggota_id', $anggota_id)
                ->selectSum('denda')
                ->get()
                ->getRow()
                ->denda ?? 0;
        }
        return $this->totalDenda();
    }

    /**
     * Grafik pengunjung harian
     */
    public function getPengunjungPerHari($awal = null, $akhir = null)
    {
        $builder = $this->db->table('pengunjung pg');

        $builder->select("
            DATE(pg.tanggal) as tanggal,
            COUNT(*) as total_pengunjung,
            GROUP_CONCAT(a.nama SEPARATOR ', ') as daftar_nama
        ");

        $builder->join('anggota a', 'a.id = pg.anggota_id', 'left');

        if ($awal != null && $akhir != null) {
            $builder->where('DATE(pg.tanggal) >=', $awal);
            $builder->where('DATE(pg.tanggal) <=', $akhir);
        }

        $builder->groupBy('DATE(pg.tanggal)');
        $builder->orderBy('pg.tanggal', 'ASC');

        return $builder->get()->getResultArray();
    }

    /**
     * Rekap mingguan
     */
    public function getRekapMingguan($tanggalAwal, $tanggalAkhir)
    {
        return $this->db->table('peminjaman')
            ->select("
                DATE(tanggal_pinjam) as tanggal,
                SUM(CASE WHEN status = 'Dikembalikan' THEN 1 ELSE 0 END) as total_pengembalian,
                SUM(COALESCE(denda, 0)) as total_denda
            ")
            ->where('tanggal_pinjam >=', $tanggalAwal)
            ->where('tanggal_pinjam <=', $tanggalAkhir)
            ->groupBy('DATE(tanggal_pinjam)')
            ->orderBy('tanggal', 'ASC')
            ->get()
            ->getResultArray();
    }

    /**
     * Rekap bulanan
     */
    public function getRekapBulanan($bulan, $tahun)
    {
        $row = $this->db->table('peminjaman')
            ->select("
                SUM(CASE WHEN status = 'Dikembalikan' THEN 1 ELSE 0 END) as total_pengembalian,
                SUM(COALESCE(denda, 0)) as total_denda
            ")
            ->where('MONTH(tanggal_pinjam)', $bulan)
            ->where('YEAR(tanggal_pinjam)', $tahun)
            ->get()
            ->getRowArray();

        return [
            'total_pengembalian' => (int)($row['total_pengembalian'] ?? 0),
            'total_denda'        => (int)($row['total_denda'] ?? 0)
        ];
    }

    /**
     * Struk denda
     */
    public function getStruk($anggota_id)
    {
        return $this->db->table('peminjaman p')
            ->select("
                p.*,
                a.id as anggota_id,
                a.nama,
                a.nisn,
                a.kelas,
                b.judul,
                b.kode_buku,
                pk.tanggal_kembali_real as tanggal_dikembalikan,
                COALESCE(pk.hari_terlambat,
                    GREATEST(
                        DATEDIFF(CURDATE(), p.tanggal_kembali),
                        0
                    ), 0
                ) as hari_terlambat
            ")
            ->join('anggota a', 'a.id=p.anggota_id')
            ->join('buku b', 'b.id=p.buku_id')
            ->join('pengembalian pk', 'pk.kode_pinjam = p.kode_pinjam', 'left')
            ->where('p.anggota_id', $anggota_id)
            ->get()
            ->getResultArray();
    }
}