<?php

namespace App\Http\Controllers;

use App\Models\Appointment;
use App\Models\AppointmentPhoto;
use App\Models\Service;
use App\Notifications\AppointmentCreatedNotification;
use App\Services\AppointmentConflictService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AppointmentController extends Controller
{
    public function index(Request $request)
    {
        $appointments = Appointment::with(['barber.user', 'service'])
            ->where('client_id', $request->user()->id)
            ->orderBy('appointment_date', 'desc')
            ->orderBy('start_time', 'desc')
            ->get();

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

    public function next(Request $request)
    {
        $appointment = Appointment::with(['barber.user', 'service'])
            ->where('client_id', $request->user()->id)
            ->whereIn('status', ['pending', 'confirmed'])
            ->where('appointment_date', '>=', Carbon::today()->toDateString())
            ->orderBy('appointment_date')
            ->orderBy('start_time')
            ->first();

        if (!$appointment) {
            return response()->json(['message' => 'No upcoming appointment'], 404);
        }

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

    public function store(Request $request)
    {
        $validated = $request->validate([
            'barber_id' => 'required|exists:barbers,id',
            'service_id' => 'required|exists:services,id',
            'appointment_date' => 'required|date|after_or_equal:today',
            'start_time' => 'required|date_format:H:i',
        ]);

        $service = Service::findOrFail($validated['service_id']);

        $endTime = Carbon::parse($validated['start_time'])->addMinutes($service->duration_minutes)->format('H:i');

        return DB::transaction(function () use ($request, $validated, $service, $endTime) {
            $dateStr = $validated['appointment_date'];
            $intervalStart = Carbon::parse($dateStr.' '.$validated['start_time']);
            $intervalEnd = Carbon::parse($dateStr.' '.$endTime);

            app(AppointmentConflictService::class)->assertBarberIntervalAvailable(
                (int) $validated['barber_id'],
                $dateStr,
                $intervalStart,
                $intervalEnd,
                null
            );

            $appointment = Appointment::create([
                'client_id' => $request->user()->id,
                'barber_id' => $validated['barber_id'],
                'service_id' => $validated['service_id'],
                'appointment_date' => $validated['appointment_date'],
                'start_time' => $validated['start_time'],
                'end_time' => $endTime,
                'status' => 'pending',
            ]);

            $appointment->load(['barber.user', 'service', 'client']);

            $appointment->client->notify(new AppointmentCreatedNotification($appointment, 'client'));
            $appointment->barber->user->notify(new AppointmentCreatedNotification($appointment, 'barber'));

            // WhatsApp «reserva_confirmada» se envía cuando el profesional o admin confirman la cita, no al crearla pendiente.

            return response()->json($appointment, 201);
        });
    }

    /**
     * Full expediente: all appointments (any status) plus photos gallery data.
     */
    public function expediente(Request $request)
    {
        $clientId = $request->user()->id;

        $appointments = Appointment::with(['barber.user', 'service', 'photos'])
            ->where('client_id', $clientId)
            ->orderBy('appointment_date', 'desc')
            ->orderBy('start_time', 'desc')
            ->get();

        $photos = AppointmentPhoto::with(['appointment.service', 'appointment.barber.user'])
            ->whereHas('appointment', fn ($q) => $q->where('client_id', $clientId))
            ->orderBy('taken_at', 'desc')
            ->get();

        return response()->json([
            'appointments' => $appointments,
            'photos' => $photos,
        ]);
    }

    public function destroy(Request $request, int $id)
    {
        $appointment = Appointment::where('id', $id)
            ->where('client_id', $request->user()->id)
            ->firstOrFail();

        $appointmentDate = Carbon::parse($appointment->appointment_date);
        if ($appointmentDate->lt(Carbon::today())) {
            return response()->json(['message' => 'Cannot cancel past appointments'], 422);
        }

        $appointment->update(['status' => 'cancelled']);
        return response()->json(['message' => 'Appointment cancelled']);
    }
}
