<?php

namespace App\Http\Controllers\Api\Attendance;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Models\Configuration;
use App\Models\EarlyDismissalSignature;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\Response;

class EarlyDismissalsController extends BaseApiController
{
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * GET /api/v1/attendance/early-dismissals
     * Returns early dismissal records grouped by report_date, plus a signature map.
     */
    public function index(Request $request): JsonResponse
    {
        $schoolYear = $request->query('school_year');
        $semester   = $request->query('semester');

        $query = DB::table('parent_attendance_reports as par')
            ->select([
                'par.id',
                'par.report_date',
                'par.dismiss_time',
                'par.reason',
                'par.status',
                'par.school_year',
                'par.semester',
                'par.class_section_id',
                's.firstname',
                's.lastname',
                'cs.class_section_name',
            ])
            ->join('students as s', 's.id', '=', 'par.student_id')
            ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'par.class_section_id')
            ->where('par.type', 'early_dismissal')
            ->orderBy('par.report_date', 'desc')
            ->orderByRaw("CONCAT(s.firstname, ' ', s.lastname) ASC");

        if ($schoolYear) {
            $query->where('par.school_year', $schoolYear);
        }
        if ($semester) {
            $query->where('par.semester', $semester);
        }

        $rows = $query->get();

        $groups = [];
        foreach ($rows as $row) {
            $date = $row->report_date ?? 'Unknown';
            $groups[$date][] = [
                'id'                 => $row->id,
                'firstname'          => $row->firstname,
                'lastname'           => $row->lastname,
                'class_section_name' => $row->class_section_name,
                'dismiss_time'       => $row->dismiss_time,
                'reason'             => $row->reason,
                'status'             => $row->status,
                'school_year'        => $row->school_year,
                'semester'           => $row->semester,
            ];
        }

        $dates = array_keys($groups);
        $signatures = EarlyDismissalSignature::query()
            ->whereIn('report_date', $dates)
            ->get(['report_date', 'filename', 'original_name']);

        $signatureByDate = [];
        foreach ($signatures as $sig) {
            $signatureByDate[(string) $sig->report_date] = [
                'filename'      => $sig->filename,
                'original_name' => $sig->original_name,
            ];
        }

        return $this->success([
            'groups'          => $groups,
            'signatureByDate' => $signatureByDate,
        ]);
    }

    /**
     * GET /api/v1/attendance/early-dismissals/student-options
     * Returns active students with their current class section.
     */
    public function studentOptions(): JsonResponse
    {
        $students = DB::table('students as s')
            ->select([
                's.id',
                's.firstname',
                's.lastname',
                'cs.class_section_name',
            ])
            ->leftJoin('student_class as sc', function ($j) {
                $j->on('sc.student_id', '=', 's.id')
                  ->where('sc.school_year', '=', Configuration::getConfigValueByKey('school_year'));
            })
            ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'sc.class_section_id')
            ->where('s.is_active', 1)
            ->orderByRaw("CONCAT(s.firstname, ' ', s.lastname) ASC")
            ->get();

        return $this->success(['students' => $students]);
    }

    /**
     * POST /api/v1/attendance/early-dismissals
     * Creates a new early dismissal record.
     */
    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'student_id'   => ['required', 'integer', 'min:1', 'exists:students,id'],
            'date'         => ['required', 'date_format:Y-m-d'],
            'dismiss_time' => ['required', 'date_format:H:i'],
            'reason'       => ['nullable', 'string', 'max:2000'],
        ]);

        if ($validator->fails()) {
            return $this->respondValidationError($validator->errors()->toArray());
        }

        $data = $validator->validated();

        $schoolYear = (string) Configuration::getConfigValueByKey('school_year');
        $semester   = (string) Configuration::getConfigValueByKey('semester');

        $sc = DB::table('student_class')
            ->where('student_id', $data['student_id'])
            ->where('school_year', $schoolYear)
            ->orderBy('id')
            ->first();

        $classSectionId = $sc?->class_section_id ?? null;

        $parentId = DB::table('students')
            ->where('id', $data['student_id'])
            ->value('parent_id') ?? Auth::id();

        DB::table('parent_attendance_reports')->insert([
            'parent_id'        => $parentId ?? Auth::id(),
            'student_id'       => $data['student_id'],
            'class_section_id' => $classSectionId,
            'report_date'      => $data['date'],
            'type'             => 'early_dismissal',
            'dismiss_time'     => $data['dismiss_time'],
            'reason'           => $data['reason'] ?? null,
            'semester'         => $semester,
            'school_year'      => $schoolYear,
            'status'           => 'new',
            'created_at'       => now(),
            'updated_at'       => now(),
        ]);

        return $this->success([], 'Early dismissal saved.', Response::HTTP_CREATED);
    }

    /**
     * POST /api/v1/attendance/early-dismissals/signature
     * Uploads (or replaces) the signature file for a report date.
     */
    public function uploadSignature(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'report_date'    => ['required', 'date_format:Y-m-d'],
            'school_year'    => ['nullable', 'string', 'max:16'],
            'semester'       => ['nullable', 'string', 'max:32'],
            'signature_file' => ['required', 'file', 'mimes:jpg,jpeg,png,webp,gif,pdf', 'max:5120'],
        ]);

        if ($validator->fails()) {
            return $this->respondValidationError($validator->errors()->toArray());
        }

        $file       = $request->file('signature_file');
        $reportDate = $request->input('report_date');
        $schoolYear = $request->input('school_year') ?: (string) Configuration::getConfigValueByKey('school_year');
        $semester   = $request->input('semester')   ?: (string) Configuration::getConfigValueByKey('semester');

        $dir      = storage_path('uploads/early_dismissal_signatures');
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        $existing = EarlyDismissalSignature::query()
            ->where('report_date', $reportDate)
            ->where('school_year', $schoolYear)
            ->where('semester', $semester)
            ->first();

        if ($existing?->filename && file_exists($dir . '/' . $existing->filename)) {
            unlink($dir . '/' . $existing->filename);
        }

        $filename = uniqid('sig_', true) . '.' . $file->getClientOriginalExtension();
        $file->move($dir, $filename);

        EarlyDismissalSignature::updateOrCreate(
            ['report_date' => $reportDate, 'school_year' => $schoolYear, 'semester' => $semester],
            [
                'filename'      => $filename,
                'original_name' => $file->getClientOriginalName(),
                'mime_type'     => $file->getClientMimeType(),
                'file_size'     => $file->getSize(),
                'uploaded_by'   => Auth::id(),
            ]
        );

        return $this->success(['filename' => $filename], 'Signature uploaded.');
    }
}
