<?php

namespace App\Http\Controllers;

use App\Models\Attendance;
use App\Models\Batch;
use App\Models\Student;
use Illuminate\Http\Request;

class AttendanceController extends Controller
{
    // GET /api/attendance/batches — batch list for dropdown
    public function batches()
    {
        $now     = now(); // Asia/Dhaka
        $today   = $now->format('l');      // e.g. "Friday"
        $nowMins = $now->hour * 60 + $now->minute; // minutes since midnight

        $batches = Batch::withCount('students')
            ->orderBy('name')
            ->get()
            ->map(function ($b) use ($today, $nowMins) {
                $schedules = $b->schedules ?? [];

                // Find schedule entries that match today
                $todaySlots = collect($schedules)->filter(
                    fn($s) => isset($s['day']) && strtolower($s['day']) === strtolower($today)
                );

                $closestDiff = null;
                foreach ($todaySlots as $slot) {
                    if (empty($slot['time'])) continue;
                    [$h, $m] = array_map('intval', explode(':', $slot['time']));
                    $slotMins = $h * 60 + $m;
                    $diff = abs($nowMins - $slotMins);
                    if ($closestDiff === null || $diff < $closestDiff) {
                        $closestDiff = $diff;
                    }
                }

                return [
                    'id'             => $b->id,
                    'name'           => $b->name,
                    'status'         => $b->status,
                    'students_count' => $b->students_count,
                    'has_today'      => $todaySlots->isNotEmpty(),
                    // smaller diff = better match; null = no schedule today
                    'time_diff_mins' => $closestDiff,
                ];
            });

        return response()->json([
            'batches'    => $batches,
            'today'      => $today,
            'now_mins'   => $nowMins,
            'server_time'=> $now->format('H:i'),
        ]);
    }

    // GET /api/attendance/students?batch_id=1&date=2026-08-21
    // Returns students of that batch with their attendance status for that date
    public function students(Request $request)
    {
        $request->validate([
            'batch_id' => 'required|exists:batches,id',
            'date'     => 'required|date',
        ]);

        $batchId = $request->batch_id;
        $date    = $request->date;

        // existing attendance records for this batch+date
        $existing = Attendance::where('batch_id', $batchId)
            ->where('date', $date)
            ->pluck('status', 'student_id');

        $students = Student::where('batch_id', $batchId)
            ->orderBy('name')
            ->get()
            ->map(fn($s) => [
                'id'          => $s->id,
                'name'        => $s->name,
                'student_id'  => $s->student_id,
                'photo_url'   => $s->photo ? asset('storage/' . $s->photo) : null,
                'initials'    => $s->initials,
                'status'      => $existing[$s->id] ?? null, // default null = unset
            ]);

        return response()->json($students);
    }

    // PATCH /api/attendance/update — update single record
    public function updateRecord(Request $request)
    {
        $request->validate([
            'batch_id'   => 'required|exists:batches,id',
            'student_id' => 'required|exists:students,id',
            'date'       => 'required|date',
            'status'     => 'required|in:present,late,absent',
        ]);

        Attendance::updateOrCreate(
            [
                'batch_id'   => $request->batch_id,
                'student_id' => $request->student_id,
                'date'       => $request->date,
            ],
            ['status' => $request->status]
        );

        return response()->json(['success' => true]);
    }

    // DELETE /api/attendance/delete-day — delete all records for a batch+date
    public function deleteDay(Request $request)
    {
        $request->validate([
            'batch_id' => 'required|exists:batches,id',
            'date'     => 'required|date',
        ]);

        $count = Attendance::where('batch_id', $request->batch_id)
            ->where('date', $request->date)
            ->delete();

        return response()->json(['success' => true, 'deleted' => $count]);
    }
    // GET /api/attendance/transfers — students who have records in multiple batches
    public function transfers()
    {
        $transferred = Attendance::selectRaw('student_id, batch_id, COUNT(*) as days')
            ->groupBy('student_id', 'batch_id')
            ->get()
            ->groupBy('student_id')
            ->filter(fn($rows) => $rows->count() > 1)
            ->map(function ($rows, $studentId) {
                $student = \App\Models\Student::with('batch')->find($studentId);
                if (!$student) return null;

                $batches = $rows->map(function ($row) use ($student) {
                    $batch = \App\Models\Batch::find($row->batch_id);

                    // All attendance records for this student in this batch
                    $batchAtt = Attendance::where('student_id', $student->id)
                        ->where('batch_id', $row->batch_id)
                        ->orderBy('date')
                        ->get();

                    $good = $batchAtt->whereIn('status', ['present','late'])->count();
                    $pct  = $batchAtt->count() > 0 ? round($good / $batchAtt->count() * 100) : null;

                    // date → status lookup
                    $records = $batchAtt->mapWithKeys(fn($a) => [
                        $a->date->format('Y-m-d') => $a->status
                    ]);
                    $dates = $batchAtt->map(fn($a) => $a->date->format('Y-m-d'))
                        ->unique()->sort()->values();

                    return [
                        'batch_id'   => $row->batch_id,
                        'batch_name' => $batch?->name ?? '—',
                        'days'       => $row->days,
                        'is_current' => $row->batch_id == $student->batch_id,
                        'att_pct'    => $pct,
                        'dates'      => $dates,
                        'records'    => $records,
                    ];
                })->sortByDesc('is_current')->values();

                return [
                    'student_id'    => $student->id,
                    'student_code'  => $student->student_id,
                    'name'          => $student->name,
                    'initials'      => $student->initials,
                    'current_batch' => $student->batch?->name ?? '—',
                    'batches'       => $batches,
                ];
            })
            ->filter()
            ->values();

        return response()->json($transferred);
    }

    // Returns cross-table: students × dates (filtered by month)
    public function history(Request $request)    {
        $request->validate([
            'batch_id' => 'required|exists:batches,id',
            'month'    => 'nullable|string',
        ]);

        $allData = $request->month === 'all';

        if ($allData) {
            // All time — no date filter
            $records = Attendance::where('batch_id', $request->batch_id)
                ->with('student:id,name,student_id')
                ->orderBy('date')
                ->get();
            $startDate = \Carbon\Carbon::now(); // dummy, not used
            $month_label = 'All Time';
            $month = 'all';
        } else {
            // Default to current month
            $month     = $request->month ?? now()->format('Y-m');
            [$year, $mon] = explode('-', $month);
            $startDate = \Carbon\Carbon::createFromDate($year, $mon, 1)->startOfMonth();
            $endDate   = $startDate->copy()->endOfMonth();
            $month_label = $startDate->format('F Y');

            $records = Attendance::where('batch_id', $request->batch_id)
                ->whereBetween('date', [$startDate, $endDate])
                ->with('student:id,name,student_id')
                ->orderBy('date')
                ->get();
        }

        // Unique sorted dates within month
        $dates = $records->pluck('date')
            ->map(fn($d) => $d->format('Y-m-d'))
            ->unique()->sort()->values();

        // All students in this batch
        // Use students who have attendance records in this batch (historical)
        // UNION with current students of this batch
        $attStudentIds = $records->pluck('student_id')->unique();
        $studentsFromAtt = \App\Models\Student::whereIn('id', $attStudentIds)
            ->orderBy('name')
            ->get(['id', 'name', 'student_id', 'joined_at', 'batch_id']);

        $currentStudents = \App\Models\Student::where('batch_id', $request->batch_id)
            ->orderBy('name')
            ->get(['id', 'name', 'student_id', 'joined_at', 'batch_id']);

        // Merge both lists, deduplicate by id
        $students = $studentsFromAtt->merge($currentStudents)
            ->unique('id')
            ->sortBy('name')
            ->values();

        // Build lookup: student_id → date → status
        $lookup = [];
        foreach ($records as $rec) {
            $lookup[$rec->student_id][$rec->date->format('Y-m-d')] = $rec->status;
        }

        $rows = $students->map(function ($s) use ($dates, $lookup) {
            $joinedAt = $s->joined_at ? $s->joined_at->format('Y-m-d') : null;

            $cells = $dates->map(function ($d) use ($s, $lookup, $joinedAt) {
                if ($joinedAt && $d < $joinedAt) {
                    return 'not_in_batch';
                }
                return $lookup[$s->id][$d] ?? null;
            });

            $total = [
                'present'  => $cells->filter(fn($v) => $v === 'present')->count(),
                'late'     => $cells->filter(fn($v) => $v === 'late')->count(),
                'absent'   => $cells->filter(fn($v) => $v === 'absent')->count(),
                'total'    => $cells->filter(fn($v) => in_array($v, ['present','late','absent']))->count(),
                'eligible' => $cells->filter(fn($v) => $v !== 'not_in_batch')->count(),
            ];

            return [
                'id'           => $s->id,
                'student_name' => $s->name,
                'student_id'   => $s->student_id,
                'joined_at'    => $joinedAt,
                'cells'        => $cells->values(),
                'total'        => $total,
            ];
        });

        // Available months that have records (for navigation)
        $availableMonths = Attendance::where('batch_id', $request->batch_id)
            ->selectRaw('DATE_FORMAT(date, "%Y-%m") as month')
            ->groupBy('month')
            ->orderBy('month', 'desc')
            ->pluck('month');

        return response()->json([
            'month'           => $month,
            'month_label'     => $month_label,
            'dates'           => $dates->values(),
            'students'        => $rows->values(),
            'available_months'=> $availableMonths,
        ]);
    }
    // GET /api/attendance/export?batch_id=1&month=2026-08  (month=all for everything)
    public function exportCsv(Request $request)
    {
        $request->validate([
            'batch_id' => 'required|exists:batches,id',
            'month'    => 'nullable|string',
        ]);

        $batch   = \App\Models\Batch::findOrFail($request->batch_id);
        $allData = $request->month === 'all';

        if ($allData) {
            $records = Attendance::where('batch_id', $request->batch_id)
                ->with('student:id,name,student_id')
                ->orderBy('date')->get();
        } else {
            $month = $request->month ?? now()->format('Y-m');
            [$year, $mon] = explode('-', $month);
            $start = \Carbon\Carbon::createFromDate($year, $mon, 1)->startOfMonth();
            $end   = $start->copy()->endOfMonth();
            $records = Attendance::where('batch_id', $request->batch_id)
                ->whereBetween('date', [$start, $end])
                ->with('student:id,name,student_id')
                ->orderBy('date')->get();
        }

        // Unique sorted dates
        $dates = $records->pluck('date')
            ->map(fn($d) => $d->format('Y-m-d'))
            ->unique()->sort()->values();

        // All students (current + historical)
        $studentIds = $records->pluck('student_id')->unique();
        $students = \App\Models\Student::whereIn('id', $studentIds)
            ->orWhere('batch_id', $request->batch_id)
            ->orderBy('name')->get(['id','name','student_id','joined_at']);
        $students = $students->unique('id')->sortBy('name')->values();

        // Lookup
        $lookup = [];
        foreach ($records as $rec) {
            $lookup[$rec->student_id][$rec->date->format('Y-m-d')] = $rec->status;
        }

        // Build CSV
        $rows   = [];
        $header = ['Student Name', 'Student ID'];
        foreach ($dates as $d) {
            $header[] = \Carbon\Carbon::parse($d)->format('d M Y (D)');
        }
        $header[] = 'Present';
        $header[] = 'Late';
        $header[] = 'Absent';
        $header[] = 'Total Classes';
        $header[] = 'Attendance %';
        $rows[]   = $header;

        foreach ($students as $s) {
            $joinedAt = $s->joined_at ? $s->joined_at->format('Y-m-d') : null;
            $row = [$s->name, $s->student_id];
            $present = $late = $absent = $eligible = 0;
            foreach ($dates as $d) {
                if ($joinedAt && $d < $joinedAt) {
                    $row[] = 'N/A';
                } else {
                    $st = $lookup[$s->id][$d] ?? null;
                    $row[] = $st === 'present' ? 'P' : ($st === 'late' ? 'L' : ($st === 'absent' ? 'A' : '—'));
                    $eligible++;
                    if ($st === 'present') $present++;
                    elseif ($st === 'late') $late++;
                    elseif ($st === 'absent') $absent++;
                }
            }
            $row[] = $present;
            $row[] = $late;
            $row[] = $absent;
            $row[] = $eligible;
            $row[] = $eligible > 0 ? round(($present + $late) / $eligible * 100) . '%' : '—';
            $rows[] = $row;
        }

        $filename = 'attendance_' . str_replace(' ', '_', $batch->name)
            . '_' . ($allData ? 'all' : ($request->month ?? now()->format('Y-m'))) . '.csv';

        $csv = implode("\n", array_map(fn($r) => implode(',', array_map(fn($v) => '"'.str_replace('"','""',$v).'"', $r)), $rows));

        return response($csv, 200, [
            'Content-Type'        => 'text/csv',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ]);
    }

    // GET /api/attendance/student?student_id=5 — full history across all batches
    public function studentHistory(Request $request)
    {
        $request->validate(['student_id' => 'required|exists:students,id']);

        $student = \App\Models\Student::with('batch')->findOrFail($request->student_id);

        // All attendance records for this student, across all batches
        $records = Attendance::where('student_id', $student->id)
            ->with('batch:id,name')
            ->orderBy('date')
            ->get();

        // Group by batch
        $byBatch = $records->groupBy('batch_id')->map(function ($batchRecords, $batchId) {
            $batch  = $batchRecords->first()->batch;
            $sorted = $batchRecords->sortBy('date')->values();

            $present = $sorted->where('status','present')->count();
            $late    = $sorted->where('status','late')->count();
            $absent  = $sorted->where('status','absent')->count();
            $total   = $sorted->count();
            $pct     = $total > 0 ? round(($present + $late) / $total * 100) : 0;

            return [
                'batch_id'   => $batchId,
                'batch_name' => $batch?->name ?? '—',
                'records'    => $sorted->map(fn($r) => [
                    'date'   => $r->date->format('Y-m-d'),
                    'status' => $r->status,
                ])->values(),
                'total'   => ['present'=>$present,'late'=>$late,'absent'=>$absent,'total'=>$total,'pct'=>$pct],
            ];
        })->values();

        return response()->json([
            'student_id'   => $student->id,
            'student_code' => $student->student_id,
            'name'         => $student->name,
            'initials'     => $student->initials,
            'current_batch'=> $student->batch?->name ?? '—',
            'batches'      => $byBatch,
        ]);
    }

    // GET /api/attendance/student/export?student_id=5
    public function exportStudentCsv(Request $request)
    {
        $request->validate(['student_id' => 'required|exists:students,id']);

        $student = \App\Models\Student::with('batch')->findOrFail($request->student_id);

        $records = Attendance::where('student_id', $student->id)
            ->with('batch:id,name')
            ->orderBy('date')
            ->get();

        // Group by batch
        $byBatch = $records->groupBy('batch_id');

        // Build CSV rows
        $rows = [];

        // Header
        $rows[] = [
            'Student Name',
            'Student ID',
            'Batch',
            'Date',
            'Day',
            'Status',
        ];

        foreach ($byBatch as $batchId => $batchRecords) {
            $batchName = $batchRecords->first()->batch?->name ?? '—';
            foreach ($batchRecords->sortBy('date') as $rec) {
                $rows[] = [
                    $student->name,
                    $student->student_id,
                    $batchName,
                    $rec->date->format('d M Y'),
                    $rec->date->format('l'),
                    ucfirst($rec->status),
                ];
            }
        }

        // Summary rows per batch
        $rows[] = []; // blank line
        $rows[] = ['--- Summary ---', '', '', '', '', ''];
        $rows[] = ['Batch', 'Present', 'Late', 'Absent', 'Total Classes', 'Attendance %'];

        foreach ($byBatch as $batchId => $batchRecords) {
            $batchName = $batchRecords->first()->batch?->name ?? '—';
            $present   = $batchRecords->where('status', 'present')->count();
            $late      = $batchRecords->where('status', 'late')->count();
            $absent    = $batchRecords->where('status', 'absent')->count();
            $total     = $batchRecords->count();
            $pct       = $total > 0 ? round(($present + $late) / $total * 100) . '%' : '—';
            $rows[]    = [$batchName, $present, $late, $absent, $total, $pct];
        }

        $filename = 'attendance_' . str_replace(' ', '_', $student->name)
            . '_' . $student->student_id . '.csv';

        $csv = implode("\n", array_map(
            fn($r) => implode(',', array_map(
                fn($v) => '"' . str_replace('"', '""', (string) $v) . '"',
                $r
            )),
            $rows
        ));

        return response($csv, 200, [
            'Content-Type'        => 'text/csv',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ]);
    }

    public function save(Request $request)
    {
        $request->validate([
            'batch_id'    => 'required|exists:batches,id',
            'date'        => 'required|date',
            'records'     => 'required|array|min:1',
            'records.*.student_id' => 'required|exists:students,id',
            'records.*.status'     => 'required|in:present,late,absent',
        ]);

        $batchId = $request->batch_id;
        $date    = $request->date;

        foreach ($request->records as $rec) {
            Attendance::updateOrCreate(
                [
                    'date'       => $date,
                    'batch_id'   => $batchId,
                    'student_id' => $rec['student_id'],
                ],
                ['status' => $rec['status']]
            );
        }

        $summary = collect($request->records)->groupBy('status')->map->count();

        return response()->json([
            'success' => true,
            'saved'   => count($request->records),
            'summary' => $summary,
        ]);
    }
}
