<?php

namespace App\Http\Controllers;

use App\Models\Batch;
use App\Models\Course;
use App\Models\Student;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class StudentController extends Controller
{
    public function index()
    {
        // Load attendance counts per student in one query
        $attCounts = \App\Models\Attendance::selectRaw(
            'student_id,
             COUNT(*) as total,
             SUM(CASE WHEN status IN ("present","late") THEN 1 ELSE 0 END) as good'
        )->groupBy('student_id')->get()->keyBy('student_id');

        $students = Student::with(['course', 'batch'])
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(fn($s) => $this->format($s, $attCounts));

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

    public function store(Request $request)
    {
        $validated = $request->validate($this->rules());

        // Auto-set joined_at when batch assigned
        if (!empty($validated['batch_id']) && empty($validated['joined_at'])) {
            $validated['joined_at'] = now()->toDateString();
        }

        $student = Student::create($validated);

        // Handle base64 photo
        if ($request->filled('photo_data')) {
            $path = $this->savePhoto($request->photo_data, $student->id);
            $student->update(['photo' => $path]);
        }

        return response()->json(['success' => true, 'id' => $student->id]);
    }

    public function update(Request $request, Student $student)
    {
        $validated = $request->validate($this->rules($student->id));

        // If batch changed, reset joined_at to today
        if (
            !empty($validated['batch_id']) &&
            (string)$validated['batch_id'] !== (string)$student->batch_id
        ) {
            $validated['joined_at'] = now()->toDateString();
        }

        $student->update($validated);

        if ($request->filled('photo_data')) {
            $path = $this->savePhoto($request->photo_data, $student->id);
            $student->update(['photo' => $path]);
        }

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

    public function destroy(Student $student)
    {
        if ($student->photo) {
            Storage::disk('public')->delete($student->photo);
        }
        $student->delete();
        return response()->json(['success' => true]);
    }

    // Bulk CSV import
    public function bulkStore(Request $request)
    {
        $request->validate([
            'students'   => 'required|array|min:1',
            'students.*' => 'array',
        ]);

        $created = 0;
        foreach ($request->students as $row) {
            $name      = trim($row['name'] ?? '');
            $studentId = trim($row['student_id'] ?? '');
            if (!$name || !$studentId) continue;

            Student::updateOrCreate(
                ['student_id' => $studentId],
                [
                    'name'        => $name,
                    'father_name' => $row['father_name'] ?? null,
                    'home_phone'  => $row['home_phone'] ?? null,
                    'phone'       => $row['phone'] ?? null,
                    'status'      => in_array($row['status'] ?? '', ['Active','Inactive']) ? $row['status'] : 'Active',
                    'course_id'   => $row['course_id'] ?: null,
                    'batch_id'    => $row['batch_id'] ?: null,
                ]
            );
            $created++;
        }

        return response()->json(['success' => true, 'count' => $created]);
    }

    // Helper: API data for courses + batches (used by JS dropdowns)
    public function formData()
    {
        return response()->json([
            'courses' => Course::orderBy('name')->get(['id', 'name']),
            'batches' => Batch::orderBy('name')->get(['id', 'name']),
        ]);
    }

    // ── Private ──────────────────────────────────────────

    private function rules(?int $ignoreId = null): array
    {
        return [
            'student_id'  => 'required|string|max:30|unique:students,student_id' . ($ignoreId ? ',' . $ignoreId : ''),
            'name'        => 'required|string|max:150',
            'father_name' => 'nullable|string|max:150',
            'home_phone'  => 'nullable|string|max:20',
            'phone'       => 'nullable|string|max:20',
            'status'      => 'required|in:Active,Inactive',
            'course_id'   => 'nullable|exists:courses,id',
            'batch_id'    => 'nullable|exists:batches,id',
            'joined_at'   => 'nullable|date',
        ];
    }

    private function format(Student $s, $attCounts = null): array
    {
        $att = $attCounts ? ($attCounts[$s->id] ?? null) : null;
        $attPct = null;
        if ($att && $att->total > 0) {
            $attPct = round(($att->good / $att->total) * 100);
        }

        return [
            'id'             => $s->id,
            'student_id'     => $s->student_id,
            'name'           => $s->name,
            'father_name'    => $s->father_name,
            'home_phone'     => $s->home_phone,
            'phone'          => $s->phone,
            'status'         => $s->status,
            'course_id'      => $s->course_id,
            'batch_id'       => $s->batch_id,
            'course_name'    => $s->course?->name ?? '—',
            'batch_name'     => $s->batch?->name ?? '—',
            'photo_url'      => $s->photo ? asset('storage/' . $s->photo) : null,
            'initials'       => $s->initials,
            'attendance_pct' => $attPct,          // null = no data
            'att_total'      => $att->total ?? 0,
        ];
    }

    private function savePhoto(string $base64, int $id): string
    {
        // strip "data:image/xxx;base64," prefix
        $data = preg_replace('/^data:image\/\w+;base64,/', '', $base64);
        $bytes = base64_decode($data);
        $path  = 'students/' . $id . '_' . time() . '.jpg';
        Storage::disk('public')->put($path, $bytes);
        return $path;
    }
}
