<?php

namespace App\Repositories;

use App\Contracts\AttendanceRecordRepositoryInterface;
use App\Models\AttendanceRecord;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

class AttendanceRecordRepository implements AttendanceRecordRepositoryInterface
{
    public function getFilteredRecords(
        ?string $month = null,
        ?string $startDate = null,
        ?string $endDate = null,
        ?int $roleId = null,
        ?string $status = null,
        string $search = '',
        int $perPage = 15,
        ?string $className = null
    ): LengthAwarePaginator {
        return AttendanceRecord::with(['user.role', 'user.shift'])
            ->when(auth()->check() && auth()->user()->hasRole('guru'), function ($q) {
                $q->whereHas('user', function ($u) {
                    $u->where('id', auth()->id())
                      ->orWhereHas('role', fn($r) => $r->where('name', 'siswa'));
                });
            })
            ->when($month !== null && $month !== '', function ($q) use ($month) {
                $dateParts = explode('-', $month);
                if (count($dateParts) == 2) {
                    $q->whereYear('date', $dateParts[0])->whereMonth('date', $dateParts[1]);
                }
            })
            ->when($startDate !== null && $startDate !== '', function ($q) use ($startDate) {
                $q->where('date', '>=', $startDate);
            })
            ->when($endDate !== null && $endDate !== '', function ($q) use ($endDate) {
                $q->where('date', '<=', $endDate);
            })
            ->when($roleId !== null, function ($q) use ($roleId) {
                $q->whereHas('user', fn($u) => $u->where('role_id', $roleId));
            })
            ->when($className !== null && $className !== '', function ($q) use ($className) {
                $q->whereHas('user', fn($u) => $u->where('class_name', $className));
            })
            ->when($status !== null && $status !== '', function ($q) use ($status) {
                $q->where('status', $status);
            })
            ->when($search !== '', function ($q) use ($search) {
                $q->whereHas('user', function ($u) use ($search) {
                    $u->where('name', 'like', "%{$search}%")
                        ->orWhere('nip_nis', 'like', "%{$search}%")
                        ->orWhere('email', 'like', "%{$search}%")
                        ->orWhere('class_name', 'like', "%{$search}%");
                });
            })
            ->orderBy('date', 'desc')
            ->latest('id')
            ->paginate($perPage);
    }

    public function getSummaryStats(
        ?string $month = null,
        ?string $startDate = null,
        ?string $endDate = null,
        ?int $roleId = null,
        ?string $className = null
    ): array {
        $query = AttendanceRecord::query()
            ->when(auth()->check() && auth()->user()->hasRole('guru'), function ($q) {
                $q->whereHas('user', function ($u) {
                    $u->where('id', auth()->id())
                      ->orWhereHas('role', fn($r) => $r->where('name', 'siswa'));
                });
            })
            ->when($month !== null && $month !== '', function ($q) use ($month) {
                $dateParts = explode('-', $month);
                if (count($dateParts) == 2) {
                    $q->whereYear('date', $dateParts[0])->whereMonth('date', $dateParts[1]);
                }
            })
            ->when($startDate !== null && $startDate !== '', fn($q) => $q->where('date', '>=', $startDate))
            ->when($endDate !== null && $endDate !== '', fn($q) => $q->where('date', '<=', $endDate))
            ->when($roleId !== null, fn($q) => $q->whereHas('user', fn($u) => $u->where('role_id', $roleId)))
            ->when($className !== null && $className !== '', fn($q) => $q->whereHas('user', fn($u) => $u->where('class_name', $className)));

        return [
            'hadir' => (clone $query)->where('status', 'Hadir')->count(),
            'pulang_cepat' => (clone $query)->where('status', 'Pulang Cepat')->count(),
            'terlambat' => (clone $query)->where('status', 'Terlambat')->count(),
            'izin' => (clone $query)->where('status', 'Izin')->count(),
            'sakit' => (clone $query)->where('status', 'Sakit')->count(),
            'alpha' => (clone $query)->where('status', 'Alpha')->count(),
            'total' => (clone $query)->count(),
        ];
    }

    public function getAllForExport(
        ?string $month = null,
        ?string $startDate = null,
        ?string $endDate = null,
        ?int $roleId = null,
        ?string $status = null,
        ?string $className = null
    ): iterable {
        return AttendanceRecord::with(['user.role', 'user.shift'])
            ->when(auth()->check() && auth()->user()->hasRole('guru'), function ($q) {
                $q->whereHas('user', function ($u) {
                    $u->where('id', auth()->id())
                      ->orWhereHas('role', fn($r) => $r->where('name', 'siswa'));
                });
            })
            ->when($month !== null && $month !== '', function ($q) use ($month) {
                $dateParts = explode('-', $month);
                if (count($dateParts) == 2) {
                    $q->whereYear('date', $dateParts[0])->whereMonth('date', $dateParts[1]);
                }
            })
            ->when($startDate !== null && $startDate !== '', fn($q) => $q->where('date', '>=', $startDate))
            ->when($endDate !== null && $endDate !== '', fn($q) => $q->where('date', '<=', $endDate))
            ->when($roleId !== null, fn($q) => $q->whereHas('user', fn($u) => $u->where('role_id', $roleId)))
            ->when($className !== null && $className !== '', fn($q) => $q->whereHas('user', fn($u) => $u->where('class_name', $className)))
            ->when($status !== null && $status !== '', fn($q) => $q->where('status', $status))
            ->orderBy('date', 'asc')
            ->cursor();
    }
}
