<?php

namespace App\Livewire;

use App\Models\AttendanceLog;
use App\Models\AttendanceRecord;
use App\Models\FingerprintMachine;
use App\Models\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\DB;
use Livewire\Component;

class Dashboard extends Component
{
    use AuthorizesRequests;

    public function render()
    {
        $today = now()->toDateString();

        // 1. Master Data & Machine Metrics
        $totalGuru = User::whereHas('role', fn($q) => $q->where('name', 'guru'))->where('is_active', true)->count();
        $totalSiswa = User::whereHas('role', fn($q) => $q->where('name', 'siswa'))->where('is_active', true)->count();
        $totalPersonil = $totalGuru + $totalSiswa;

        $machines = FingerprintMachine::all();
        $totalMesin = $machines->count();

        // Use calculatedStatus() (real-time from last_seen_at) NOT stored 'status' column
        $mesinOnline = $machines->filter(fn($m) => $m->calculatedStatus() === 'online')->count();
        $mesinStale = $machines->filter(fn($m) => $m->calculatedStatus() === 'stale')->count();
        $mesinOffline = $machines->filter(fn($m) => $m->calculatedStatus() === 'offline')->count();
        $mesinNeverConnected = $machines->filter(fn($m) => $m->calculatedStatus() === 'never_connected')->count();

        $syncHariIni = AttendanceLog::whereDate('created_at', $today)->count();

        // Today's total attendance scans ingested
        $todayScanCount = AttendanceLog::whereDate('timestamp', $today)->count();

        // 2. Count status hari ini
        $statusHariIni = AttendanceRecord::whereDate('date', $today)
            ->select('status', DB::raw('count(*) as total'))
            ->groupBy('status')
            ->pluck('total', 'status');

        $totalHadir = $statusHariIni->get('Hadir', 0);
        $totalTerlambat = $statusHariIni->get('Terlambat', 0);
        $totalIzin = $statusHariIni->get('Izin', 0);
        $totalSakit = $statusHariIni->get('Sakit', 0);
        $totalAlpha = $statusHariIni->get('Alpha', 0);

        $kehadiranHariIniCount = $totalHadir + $totalTerlambat;
        $kehadiranHariIniPersen = $totalPersonil > 0 ? round(($kehadiranHariIniCount / $totalPersonil) * 100, 1) : 0;

        // Breakdown Terlambat per Role
        $guruTerlambat = AttendanceRecord::whereDate('date', $today)
            ->where('status', 'Terlambat')
            ->whereHas('user.role', fn($q) => $q->where('name', 'guru'))
            ->count();

        $siswaTerlambat = AttendanceRecord::whereDate('date', $today)
            ->where('status', 'Terlambat')
            ->whereHas('user.role', fn($q) => $q->where('name', 'siswa'))
            ->count();

        // Analytics Base Data (30 Hari Terakhir)
        $thirtyDaysAgo = now()->subDays(29)->toDateString();
        $dailyRecords = AttendanceRecord::selectRaw('DATE(date) as date_val, status, count(*) as count')
            ->whereDate('date', '>=', $thirtyDaysAgo)
            ->groupBy('date_val', 'status')
            ->get()
            ->groupBy('date_val');

        // 3. Analytics Grafik Mingguan (7 Hari Terakhir)
        $grafikMingguan = [];
        for ($i = 6; $i >= 0; $i--) {
            $d = now()->subDays($i)->toDateString();
            $recordsToday = $dailyRecords->get($d, collect());
            $hadir = $recordsToday->whereIn('status', ['Hadir', 'Terlambat'])->sum('count');
            $alpha = $recordsToday->where('status', 'Alpha')->sum('count');
            $grafikMingguan[] = [
                'day' => now()->subDays($i)->translatedFormat('D, d M'),
                'hadir' => $hadir,
                'alpha' => $alpha,
            ];
        }

        // 4. Analytics Grafik Bulanan (30 Hari Terakhir Aggregate)
        $grafikBulanan = [];
        for ($i = 29; $i >= 0; $i -= 3) {
            $count = 0;
            // Sum 3 days from memory
            for ($j = $i; $j >= max(0, $i - 2); $j--) {
                $d = now()->subDays($j)->toDateString();
                $count += $dailyRecords->get($d, collect())->whereIn('status', ['Hadir', 'Terlambat'])->sum('count');
            }
            $grafikBulanan[] = [
                'label' => now()->subDays($i)->format('d/m'),
                'total' => $count,
            ];
        }

        // 5. Heatmap Kehadiran (30 Hari Terakhir dengan Level Intensitas 0 - 4)
        $heatmapKehadiran = [];
        for ($i = 29; $i >= 0; $i--) {
            $d = now()->subDays($i)->toDateString();
            $count = $dailyRecords->get($d, collect())->whereIn('status', ['Hadir', 'Terlambat'])->sum('count');
            
            // Tentukan Level Intensitas (0: Sepi, 1: Low, 2: Mid, 3: High, 4: Full)
            $level = 0;
            if ($count > 0) {
                if ($count <= 5) $level = 1;
                elseif ($count <= 15) $level = 2;
                elseif ($count <= 30) $level = 3;
                else $level = 4;
            }

            $heatmapKehadiran[] = [
                'date' => $d,
                'day_num' => now()->subDays($i)->format('d'),
                'count' => $count,
                'level' => $level,
            ];
        }

        // 6. Trend Kehadiran (% Minggu Ini vs Minggu Lalu)
        $thisWeekStart = now()->startOfWeek()->toDateString();
        $lastWeekStart = now()->subWeek()->startOfWeek()->toDateString();
        $lastWeekEnd = now()->subWeek()->endOfWeek()->toDateString();

        $thisWeekCount = AttendanceRecord::whereDate('date', '>=', $thisWeekStart)->whereIn('status', ['Hadir', 'Terlambat'])->count();
        $lastWeekCount = AttendanceRecord::whereBetween('date', [$lastWeekStart, $lastWeekEnd])->whereIn('status', ['Hadir', 'Terlambat'])->count();

        $trendPersen = 0;
        if ($lastWeekCount > 0) {
            $trendPersen = round((($thisWeekCount - $lastWeekCount) / $lastWeekCount) * 100, 1);
        }

        // 7. Top 5 Terlambat & Top 5 Alpha bulan ini
        $startOfMonth = now()->startOfMonth()->toDateString();
        $topTerlambat = AttendanceRecord::select('user_id', DB::raw('count(*) as total'))
            ->whereDate('date', '>=', $startOfMonth)
            ->where('status', 'Terlambat')
            ->groupBy('user_id')
            ->orderBy('total', 'desc')
            ->with('user.role')
            ->limit(5)
            ->get();

        $topAlpha = AttendanceRecord::select('user_id', DB::raw('count(*) as total'))
            ->whereDate('date', '>=', $startOfMonth)
            ->where('status', 'Alpha')
            ->groupBy('user_id')
            ->orderBy('total', 'desc')
            ->with('user.role')
            ->limit(5)
            ->get();

        // Aktivitas Sinkronisasi Terkini dari AttendanceLog (Push API)
        $latestSyncLogs = AttendanceLog::with('machine')->latest()->limit(5)->get();

        return view('livewire.dashboard', [
            'totalGuru' => $totalGuru,
            'totalSiswa' => $totalSiswa,
            'totalMesin' => $totalMesin,
            'mesinOnline' => $mesinOnline,
            'mesinStale' => $mesinStale,
            'mesinOffline' => $mesinOffline,
            'mesinNeverConnected' => $mesinNeverConnected,
            'syncHariIni' => $syncHariIni,
            'todayScanCount' => $todayScanCount,
            'totalHadir' => $totalHadir,
            'totalTerlambat' => $totalTerlambat,
            'totalIzin' => $totalIzin,
            'totalSakit' => $totalSakit,
            'totalAlpha' => $totalAlpha,
            'kehadiranHariIniCount' => $kehadiranHariIniCount,
            'kehadiranHariIniPersen' => $kehadiranHariIniPersen,
            'guruTerlambat' => $guruTerlambat,
            'siswaTerlambat' => $siswaTerlambat,
            'grafikMingguan' => $grafikMingguan,
            'grafikBulanan' => $grafikBulanan,
            'heatmapKehadiran' => $heatmapKehadiran,
            'thisWeekCount' => $thisWeekCount,
            'lastWeekCount' => $lastWeekCount,
            'trendPersen' => $trendPersen,
            'machines' => $machines,
            'topTerlambat' => $topTerlambat,
            'topAlpha' => $topAlpha,
            'latestSyncLogs' => $latestSyncLogs,
        ])->layout('components.layouts.app');
    }
}
