<?php

namespace App\Filament\Widgets;

use App\Models\Attendance;
use App\Models\BusinessTrip;
use App\Models\Document;
use App\Models\User;
use Carbon\Carbon;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class StatsOverview extends BaseWidget
{
    protected static ?string $pollingInterval = '30s';

    protected static ?int $sort = 1;

    protected int | string | array $columnSpan = 'full';

    protected function getStats(): array
    {
        $today = now()->toDateString();
        $thisMonth = now()->month;
        $thisYear = now()->year;

        // User stats (hide super_admin)
        $totalUsers = User::whereDoesntHave('roles', fn ($q) => $q->where('name', 'super_admin'))->count();
        $activeUsers = User::where('is_active', true)
            ->whereDoesntHave('roles', fn ($q) => $q->where('name', 'super_admin'))
            ->count();
        $pendingApprovalUsers = User::where('approval_status', 'pending')
            ->whereDoesntHave('roles', fn ($q) => $q->where('name', 'super_admin'))
            ->count();

        // Attendance today (hide super_admin)
        $attendanceToday = Attendance::whereDate('date', $today)
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();
        $lateToday = Attendance::whereDate('date', $today)
            ->where('status', 'late')
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();
        $presentToday = Attendance::whereDate('date', $today)
            ->where('status', 'present')
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();

        // Get attendance trend for last 7 days (hide super_admin)
        $attendanceTrend = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            $attendanceTrend[] = Attendance::whereDate('date', $date)
                ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
                ->count();
        }

        // Business trips (hide super_admin)
        $pendingTrips = BusinessTrip::where('status', 'pending')
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();
        $ongoingTrips = BusinessTrip::where('status', 'ongoing')
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();
        $completedThisMonth = BusinessTrip::where('status', 'completed')
            ->whereMonth('end_date', $thisMonth)
            ->whereYear('end_date', $thisYear)
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();

        // Documents (hide super_admin)
        $pendingDocuments = Document::where('status', 'pending')
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();
        $approvedDocumentsThisMonth = Document::where('status', 'approved')
            ->whereMonth('approved_at', $thisMonth)
            ->whereYear('approved_at', $thisYear)
            ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
            ->count();

        return [
            Stat::make('Total Karyawan Aktif', number_format($activeUsers))
                ->description($pendingApprovalUsers > 0 ? $pendingApprovalUsers . ' menunggu approval' : 'Semua terverifikasi')
                ->descriptionIcon($pendingApprovalUsers > 0 ? 'heroicon-m-clock' : 'heroicon-m-check-circle')
                ->color($pendingApprovalUsers > 0 ? 'warning' : 'success')
                ->chart($this->getUserTrend())
                ->extraAttributes([
                    'class' => 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200',
                ]),

            Stat::make('Kehadiran Hari Ini', $attendanceToday . ' / ' . $activeUsers)
                ->description($this->getAttendanceDescription($presentToday, $lateToday))
                ->descriptionIcon($lateToday > 0 ? 'heroicon-m-exclamation-triangle' : 'heroicon-m-check-circle')
                ->color($this->getAttendanceColor($presentToday, $lateToday, $activeUsers))
                ->chart($attendanceTrend)
                ->extraAttributes([
                    'class' => 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200',
                ]),

            Stat::make('Perjalanan Dinas', $ongoingTrips . ' sedang berlangsung')
                ->description($this->getBusinessTripDescription($pendingTrips, $completedThisMonth))
                ->descriptionIcon($pendingTrips > 0 ? 'heroicon-m-clock' : 'heroicon-m-paper-airplane')
                ->color($pendingTrips > 0 ? 'warning' : 'info')
                ->chart($this->getBusinessTripTrend())
                ->extraAttributes([
                    'class' => 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200',
                ]),

            Stat::make('Dokumen', $this->getDocumentSummary($pendingDocuments, $approvedDocumentsThisMonth))
                ->description($pendingDocuments > 0 ? $pendingDocuments . ' menunggu approval' : 'Semua terverifikasi')
                ->descriptionIcon($pendingDocuments > 0 ? 'heroicon-m-document-text' : 'heroicon-m-check-circle')
                ->color($pendingDocuments > 0 ? 'warning' : 'success')
                ->chart($this->getDocumentTrend())
                ->extraAttributes([
                    'class' => 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200',
                ]),
        ];
    }

    private function getUserTrend(): array
    {
        $trend = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            $trend[] = User::whereDate('created_at', '<=', $date)
                ->where('is_active', true)
                ->whereDoesntHave('roles', fn ($q) => $q->where('name', 'super_admin'))
                ->count();
        }
        return $trend;
    }

    private function getBusinessTripTrend(): array
    {
        $trend = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            $trend[] = BusinessTrip::whereDate('created_at', $date)
                ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
                ->count();
        }
        return $trend;
    }

    private function getDocumentTrend(): array
    {
        $trend = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = now()->subDays($i)->toDateString();
            $trend[] = Document::whereDate('created_at', $date)
                ->whereHas('user', fn ($q) => $q->whereDoesntHave('roles', fn ($r) => $r->where('name', 'super_admin')))
                ->count();
        }
        return $trend;
    }

    private function getAttendanceDescription(int $present, int $late): string
    {
        if ($late > 0) {
            return $present . ' hadir tepat waktu, ' . $late . ' terlambat';
        }
        return $present . ' hadir tepat waktu';
    }

    private function getAttendanceColor(int $present, int $late, int $total): string
    {
        $percentage = $total > 0 ? ($present / $total) * 100 : 0;

        if ($percentage >= 90) return 'success';
        if ($percentage >= 70) return 'info';
        if ($percentage >= 50) return 'warning';
        return 'danger';
    }

    private function getBusinessTripDescription(int $pending, int $completed): string
    {
        $parts = [];
        if ($pending > 0) $parts[] = $pending . ' pending';
        if ($completed > 0) $parts[] = $completed . ' selesai bulan ini';

        return count($parts) > 0 ? implode(', ', $parts) : 'Tidak ada aktivitas';
    }

    private function getDocumentSummary(int $pending, int $approved): string
    {
        if ($pending > 0) {
            return $pending . ' pending';
        }
        return $approved . ' disetujui bulan ini';
    }
}
