<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class SendDailyAttendance extends BaseCommand
{
    protected $group       = 'Cron';
    protected $name        = 'app:send-daily-attendance';
    protected $description = 'Kirim rekap absensi harian siswa yang tidak masuk ke grup WhatsApp otomatis';
    protected $options     = [
        '-f, --force' => 'Abaikan pengecekan hari libur/Minggu dan kirim rekap secara paksa',
    ];

    public function run(array $params)
    {
        $db = \Config\Database::connect();
        
        $todayDate   = date('Y-m-d');
        $todayDayNum = (int)date('N'); // 1 = Senin, ..., 7 = Minggu

        log_message('info', "SendDailyAttendance: Command started. Date: {$todayDate}, Day: {$todayDayNum}");

        $force = CLI::getOption('force') !== null;
        if (!$force) {
            if (array_key_exists('force', $params) || array_key_exists('f', $params) || in_array('--force', $params) || in_array('-f', $params)) {
                $force = true;
            }
        }

        // 1. Cek Hari Libur jika tidak dipaksa (--force)
        if (!$force) {
            if ($todayDayNum === 7) { // Hari Minggu
                CLI::write("Hari ini Hari Minggu. Pengiriman dibatalkan.", 'yellow');
                return;
            }

            // Cek apakah hari Sabtu diatur libur
            $sabtuLiburRow = $db->table('calendar_settings')->where('key', 'sabtu_libur')->get()->getRowArray();
            $sabtuLibur = $sabtuLiburRow && (int)$sabtuLiburRow['value'] === 1;
            if ($todayDayNum === 6 && $sabtuLibur) {
                CLI::write("Hari ini Hari Sabtu dan diatur libur. Pengiriman dibatalkan.", 'yellow');
                return;
            }

            // Cek libur kalender akademik
            $holiday = $db->table('calendar_events ce')
                ->join('calendar_categories cc', 'cc.id = ce.category_id')
                ->where('cc.is_libur', 1)
                ->where('ce.deleted_at', null)
                ->where('ce.start_date <=', $todayDate)
                ->where('ce.end_date >=', $todayDate)
                ->countAllResults();

            if ($holiday > 0) {
                CLI::write("Hari ini adalah hari libur kalender akademik. Pengiriman dibatalkan.", 'yellow');
                log_message('info', "SendDailyAttendance: Canceled, today is academic holiday.");
                return;
            }
        }

        // 2. Inisialisasi WhatsappService
        $waService = new \App\Services\WhatsappService();
        if (!$waService->isConfigured()) {
            CLI::error("Whatsapp Gateway belum terkonfigurasi dengan benar di Pengaturan!");
            log_message('error', "SendDailyAttendance: WhatsApp Gateway belum terkonfigurasi.");
            return;
        }

        if (!$waService->isFeatureEnabled('attendance')) {
            CLI::write("Fitur pengiriman rekap absensi harian via WhatsApp dinonaktifkan di Pengaturan.", 'light_blue');
            log_message('info', "SendDailyAttendance: Fitur pengiriman rekap absensi WhatsApp dinonaktifkan.");
            return;
        }

        $groupId = $waService->getGroupIdAttendance();
        if (empty($groupId)) {
            CLI::error("ID Grup WhatsApp tujuan absensi belum diisi di Pengaturan!");
            log_message('error', "SendDailyAttendance: ID Grup WhatsApp Absensi kosong.");
            return;
        }

        // 3. Ambil Mode Absensi Aktif (manual / qr)
        $attModeRow = $db->table('settings')->where('setting_key', 'attendance_mode')->get()->getRowArray();
        $attendanceMode = $attModeRow['setting_value'] ?? 'manual';
        CLI::write("Mode Absensi Aktif: " . strtoupper($attendanceMode));

        // 4. Ambil Periode Akademik Aktif
        $activePeriod = $db->table('academic_periods')->where('is_active', 1)->get()->getRowArray();
        $periodId = $activePeriod ? $activePeriod['id'] : null;
        if (!$periodId) {
            CLI::error("Tidak ada periode akademik aktif. Pengiriman dibatalkan.");
            log_message('error', "SendDailyAttendance: Periode akademik aktif tidak ditemukan.");
            return;
        }

        // 5. Ambil Daftar Kelas (Diurutkan berdasarkan grade order, lalu nama kelas)
        $classrooms = $db->table('classrooms c')
            ->select('c.id, c.name, g.name as grade_name')
            ->join('grades g', 'g.id = c.grade_id', 'left')
            ->orderBy('g.order', 'ASC')
            ->orderBy('c.name', 'ASC')
            ->get()->getResultArray();

        if (empty($classrooms)) {
            CLI::write("Tidak ada data kelas.", 'yellow');
            return;
        }

        // Persiapan Tanggal format Indonesia
        $daysMap = [
            1 => 'Senin', 2 => 'Selasa', 3 => 'Rabu', 4 => 'Kamis', 5 => 'Jumat', 6 => 'Sabtu', 7 => 'Minggu'
        ];
        $monthsMap = [
            1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni',
            7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'
        ];
        $dayName = $daysMap[$todayDayNum] ?? '';
        $dateFormatted = date('d') . ' ' . ($monthsMap[(int)date('m')] ?? '') . ' ' . date('Y');
        $todayStringIndo = "$dayName, $dateFormatted";

        // Ambil Data Absensi Berdasarkan Mode
        $totalAbsent = 0;
        $totalAlpha = 0;
        $totalSakit = 0;
        $totalIzin = 0;

        $msgBody = "";

        foreach ($classrooms as $class) {
            // Ambil semua murid aktif di kelas ini pada periode akademik aktif
            $studentsInClass = $db->table('students s')
                ->join('student_academic_histories sah', "sah.student_id = s.id AND sah.academic_period_id = {$periodId}", 'inner')
                ->where('sah.classroom_id', $class['id'])
                ->where('s.deleted_at', null)
                ->where('s.status', 'Aktif')
                ->orderBy('s.full_name', 'ASC')
                ->get()->getResultArray();

            $totalStudents = count($studentsInClass);
            if ($totalStudents === 0) {
                continue;
            }

            // Ambil record scan QR atau manual absen
            $absentList = []; // Daftar murid tidak hadir
            $presentCount = 0;

            foreach ($studentsInClass as $student) {
                $status = 'hadir'; // default

                if ($attendanceMode === 'qr') {
                    // Cek QR scan log
                    $scanned = $db->table('qr_scan_logs')
                        ->where('student_id', $student['id'])
                        ->where('date', $todayDate)
                        ->countAllResults() > 0;

                    if ($scanned) {
                        $status = 'hadir';
                    } else {
                        // Cek manual (sakit/izin/alpha)
                        $att = $db->table('attendances')
                            ->where('student_id', $student['id'])
                            ->where('academic_period_id', $periodId)
                            ->where('date', $todayDate)
                            ->get()->getRowArray();
                        
                        $status = $att['status'] ?? 'belum';
                    }
                } else {
                    // Manual mode: Cek attendances
                    $att = $db->table('attendances')
                        ->where('student_id', $student['id'])
                        ->where('academic_period_id', $periodId)
                        ->where('date', $todayDate)
                        ->get()->getRowArray();
                    
                    $status = $att['status'] ?? 'hadir'; // Jika tidak ada di tabel, default hadir
                }

                if (in_array($status, ['Sakit', 'Izin', 'Alpha', 'belum'])) {
                    if ($status === 'belum' && $attendanceMode === 'qr') {
                        // Di mode QR, jika belum scan dan tidak ada keterangan, dianggap Alpha
                        $status = 'Alpha';
                    }

                    if ($status !== 'hadir') {
                        $absentList[] = [
                            'name' => $student['full_name'],
                            'status' => $status
                        ];

                        $totalAbsent++;
                        if ($status === 'Alpha') $totalAlpha++;
                        if ($status === 'Sakit') $totalSakit++;
                        if ($status === 'Izin') $totalIzin++;
                    } else {
                        $presentCount++;
                    }
                } else {
                    $presentCount++;
                }
            }

            // Susun baris kelas
            $msgBody .= "*Kelas {$class['name']}* ({$totalStudents} siswa) — ";
            if (empty($absentList)) {
                $msgBody .= "Semua Hadir ✅\n";
            } else {
                $msgBody .= "Hadir: {$presentCount} | Tidak: " . count($absentList) . "\n";
                foreach ($absentList as $abs) {
                    $msgBody .= "  • {$abs['name']} — *{$abs['status']}*\n";
                }
            }
            $msgBody .= "\n";
        }

        // Susun header pesan
        helper('url');
        $baseUrl = rtrim(base_url(), '/');

        $msg  = "📊 *REKAP ABSENSI HARIAN SISWA*\n";
        $msg .= "MIS DARUSSALAM ADIJAYA\n";
        $msg .= "Hari: *{$todayStringIndo}*\n";
        $msg .= "──────────────\n\n";
        
        $msg .= $msgBody;
        
        $msg .= "──────────────\n";
        $msg .= "📌 *TOTAL TIDAK HADIR: {$totalAbsent} siswa*\n";
        $msg .= "Alpha: {$totalAlpha} | Sakit: {$totalSakit} | Izin: {$totalIzin}\n\n";
        $msg .= "_Pesan dikirim otomatis dari aplikasi SIMAK - {$baseUrl}_";

        CLI::write("Mengirim rekap absensi ke grup: $groupId ...");
        
        // Kirim via WhatsappService ke Group ID (isGroup = true)
        $result = $waService->send($groupId, $msg, true);

        if ($result['success']) {
            CLI::write("Rekap absensi berhasil dikirim ke grup!", 'green');
            log_message('info', "SendDailyAttendance: Rekap absensi berhasil dikirim ke grup {$groupId}.");
        } else {
            CLI::error("Gagal mengirim rekap absensi. Error: " . $result['message']);
            log_message('error', "SendDailyAttendance: Gagal mengirim ke grup {$groupId}. Error: " . $result['message']);
        }
    }
}
