<?php

namespace App\Http\Controllers;

use App\Models\Service;
use App\Models\Barber;
use App\Services\SlotService;
use Carbon\Carbon;
use Illuminate\Http\Request;

class PublicController extends Controller
{
    /**
     * Evita que el navegador o un proxy cachee listados dinámicos (servicios, marca, etc.).
     */
    private function jsonNoStore($data, int $status = 200)
    {
        return response()->json($data, $status)->withHeaders([
            'Cache-Control' => 'private, no-cache, no-store, must-revalidate',
            'Pragma' => 'no-cache',
        ]);
    }

    /**
     * Return public app branding settings (name + logo).
     */
    public function settings()
    {
        $themeCustomRaw = \App\Models\AppSetting::getValue('theme_custom_vars');
        $themeCustomVars = null;
        if ($themeCustomRaw !== null && $themeCustomRaw !== '') {
            $decoded = json_decode((string) $themeCustomRaw, true);
            $themeCustomVars = is_array($decoded) ? $decoded : null;
        }

        return $this->jsonNoStore([
            'business_name' => \App\Models\AppSetting::getValue('business_name', 'Barbería DIAICR'),
            'logo_url' => \App\Models\AppSetting::getValue('logo_url', '/logo.png'),
            'theme_id' => \App\Models\AppSetting::getValue('theme_id', 'obsidiana'),
            'theme_custom_vars' => $themeCustomVars,
            'background_url' => \App\Models\AppSetting::getValue('background_url'),
            'label_staff_singular' => \App\Models\AppSetting::getValue('label_staff_singular', 'Profesional'),
            'label_staff_plural' => \App\Models\AppSetting::getValue('label_staff_plural', 'Profesionales'),
            'menu_icon_staff' => \App\Models\AppSetting::getValue('menu_icon_staff', '💈'),
            'menu_icon_services' => \App\Models\AppSetting::getValue('menu_icon_services', '✂️'),
            'calendars_collapsed_default' => filter_var(\App\Models\AppSetting::getValue('calendars_collapsed_default', '0'), FILTER_VALIDATE_BOOLEAN),
            'inbox_confirm_actions' => filter_var(\App\Models\AppSetting::getValue('inbox_confirm_actions', '1'), FILTER_VALIDATE_BOOLEAN),
            'reminder_minutes_before' => (int) \App\Models\AppSetting::getValue('reminder_minutes_before', '15'),
            'reminder_notify_client' => filter_var(\App\Models\AppSetting::getValue('reminder_notify_client', '1'), FILTER_VALIDATE_BOOLEAN),
            'reminder_notify_barber' => filter_var(\App\Models\AppSetting::getValue('reminder_notify_barber', '1'), FILTER_VALIDATE_BOOLEAN),
            /** Dígitos para wa.me (app cliente); vacío si no configurado */
            'public_whatsapp_phone' => (string) \App\Models\AppSetting::getValue('public_whatsapp_phone', ''),
        ]);
    }

    /**
     * Return VAPID public key for Web Push subscription (used by frontend).
     */
    public function vapidKey()
    {
        $key = config('webpush.public_key');

        return $this->jsonNoStore(['key' => $key ?: null]);
    }

    public function services()
    {
        return $this->jsonNoStore(
            Service::where('is_active', true)
                ->orderBy('category')
                ->orderBy('name')
                ->get()
        );
    }

    public function barbers()
    {
        $barbers = Barber::with(['user', 'services' => function ($query) {
            $query->where('is_active', true);
        }])->get()->filter(function ($barber) {
            return $barber->user->is_active && $barber->services->isNotEmpty();
        })->values();

        return $this->jsonNoStore($barbers);
    }

    public function slots(Request $request, SlotService $slotService)
    {
        $request->validate([
            'barber_id' => 'required|exists:barbers,id',
            'service_id' => 'required|exists:services,id',
            'date' => 'required|date',
        ]);

        $slots = $slotService->getAvailableSlots(
            $request->barber_id,
            $request->service_id,
            $request->date
        );

        return $this->jsonNoStore($slots);
    }

    /**
     * Dates in range with at least one bookable slot (for calendar UI).
     */
    public function availableDates(Request $request, SlotService $slotService)
    {
        $validated = $request->validate([
            'barber_id' => 'required|exists:barbers,id',
            'service_id' => 'required|exists:services,id',
            'from' => 'required|date',
            'to' => 'required|date|after_or_equal:from',
        ]);

        $from = Carbon::parse($validated['from'])->startOfDay();
        $to = Carbon::parse($validated['to'])->startOfDay();
        if ($from->diffInDays($to) > 120) {
            return response()->json(['message' => 'El rango no puede superar 120 días.'], 422);
        }

        $dates = $slotService->datesWithAvailability(
            (int) $validated['barber_id'],
            (int) $validated['service_id'],
            $from->toDateString(),
            $to->toDateString()
        );

        return $this->jsonNoStore(['dates' => $dates]);
    }
}
