<?php

use App\Enums\ConsultationStatus;
use App\Enums\PaymentStatus;
use App\Mail\GuestBookingSubmittedMail;
use App\Mail\NewBookingAdminEmail;
use App\Models\Consultation;
use App\Models\User;
use App\Services\AvailabilityService;
use App\Services\CaptchaService;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\RateLimiter;
use Livewire\Attributes\Layout;
use Livewire\Volt\Component;

new #[Layout('components.layouts.public')] class extends Component
{
    public ?string $selectedDate = null;

    public ?string $selectedTime = null;

    public string $guestName = '';

    public string $guestEmail = '';

    public string $guestPhone = '';

    public string $problemSummary = '';

    public string $captchaAnswer = '';

    public array $captchaQuestion = [];

    public bool $showConfirmation = false;

    public bool $isLoggedIn = false;

    public function mount(): void
    {
        // Check if user is logged in - show friendly message instead of booking form
        if (auth()->check()) {
            $this->isLoggedIn = true;

            return;
        }

        $this->refreshCaptcha();
    }

    public function refreshCaptcha(): void
    {
        $this->captchaQuestion = app(CaptchaService::class)->generate();
        $this->captchaAnswer = '';
    }

    public function selectSlot(string $date, string $time): void
    {
        $this->selectedDate = $date;
        $this->selectedTime = $time;
    }

    public function clearSelection(): void
    {
        $this->selectedDate = null;
        $this->selectedTime = null;
        $this->showConfirmation = false;
    }

    public function showConfirm(): void
    {
        $this->validate([
            'selectedDate' => ['required', 'date', 'after_or_equal:today'],
            'selectedTime' => ['required'],
            'guestName' => ['required', 'string', 'min:3', 'max:255'],
            'guestEmail' => ['required', 'email', 'max:255'],
            'guestPhone' => ['required', 'string', 'max:50'],
            'problemSummary' => ['required', 'string', 'min:20', 'max:2000'],
            'captchaAnswer' => ['required'],
        ]);

        // Validate captcha
        if (! app(CaptchaService::class)->validate($this->captchaAnswer)) {
            $this->addError('captchaAnswer', __('booking.invalid_captcha'));
            $this->refreshCaptcha();

            return;
        }

        // Check 1-per-day limit for this email
        $existingBooking = Consultation::query()
            ->where('guest_email', $this->guestEmail)
            ->whereDate('booking_date', $this->selectedDate)
            ->whereIn('status', [ConsultationStatus::Pending, ConsultationStatus::Approved])
            ->exists();

        if ($existingBooking) {
            $this->addError('guestEmail', __('booking.guest_already_booked_this_day'));

            return;
        }

        // Verify slot still available
        $service = app(AvailabilityService::class);
        $availableSlots = $service->getAvailableSlots(Carbon::parse($this->selectedDate));

        if (! in_array($this->selectedTime, $availableSlots)) {
            $this->addError('selectedTime', __('booking.slot_no_longer_available'));

            return;
        }

        $this->showConfirmation = true;
    }

    public function submit(): void
    {
        // Rate limiting by IP
        $ipKey = 'guest-booking:'.request()->ip();
        if (RateLimiter::tooManyAttempts($ipKey, 5)) {
            $this->addError('guestEmail', __('booking.too_many_attempts'));

            return;
        }
        RateLimiter::hit($ipKey, 60 * 60 * 24); // 24 hours

        try {
            DB::transaction(function () {
                // Double-check slot availability with lock
                $slotTaken = Consultation::query()
                    ->whereDate('booking_date', $this->selectedDate)
                    ->where('booking_time', $this->selectedTime)
                    ->whereIn('status', [ConsultationStatus::Pending, ConsultationStatus::Approved])
                    ->lockForUpdate()
                    ->exists();

                if ($slotTaken) {
                    throw new \Exception(__('booking.slot_taken'));
                }

                // Double-check 1-per-day with lock
                $emailHasBooking = Consultation::query()
                    ->where('guest_email', $this->guestEmail)
                    ->whereDate('booking_date', $this->selectedDate)
                    ->whereIn('status', [ConsultationStatus::Pending, ConsultationStatus::Approved])
                    ->lockForUpdate()
                    ->exists();

                if ($emailHasBooking) {
                    throw new \Exception(__('booking.guest_already_booked_this_day'));
                }

                // Create guest consultation
                $consultation = Consultation::create([
                    'user_id' => null,
                    'guest_name' => $this->guestName,
                    'guest_email' => $this->guestEmail,
                    'guest_phone' => $this->guestPhone,
                    'booking_date' => $this->selectedDate,
                    'booking_time' => $this->selectedTime,
                    'problem_summary' => $this->problemSummary,
                    'status' => ConsultationStatus::Pending,
                    'payment_status' => PaymentStatus::NotApplicable,
                ]);

                // Send confirmation to guest
                Mail::to($this->guestEmail)->queue(
                    new GuestBookingSubmittedMail($consultation)
                );

                // Notify admin
                $admin = User::query()->where('user_type', 'admin')->first();
                if ($admin) {
                    Mail::to($admin)->queue(
                        new NewBookingAdminEmail($consultation)
                    );
                }
            });

            // Clear captcha
            app(CaptchaService::class)->clear();

            session()->flash('success', __('booking.guest_submitted_successfully'));
            $this->redirect(route('booking.success'));

        } catch (\Exception $e) {
            $this->addError('selectedTime', $e->getMessage());
            $this->showConfirmation = false;
            $this->refreshCaptcha();
        }
    }
}; ?>

<div class="max-w-4xl mx-auto py-8 px-4">
        <flux:heading size="xl" class="mb-6 text-body">
            {{ __('booking.request_consultation') }}
        </flux:heading>

        @if($isLoggedIn)
            {{-- Logged-in user message --}}
            <div class="bg-white rounded-lg shadow-sm border border-amber-200 p-8 text-center">
                <div class="mb-6">
                    <div class="mx-auto w-16 h-16 bg-amber-100 rounded-full flex items-center justify-center mb-4">
                        <flux:icon name="user-circle" class="w-8 h-8 text-amber-600" />
                    </div>
                    <flux:heading size="lg" class="text-body mb-2">
                        {{ __('booking.logged_in_title') }}
                    </flux:heading>
                    <p class="text-zinc-600 max-w-md mx-auto">
                        {{ __('booking.logged_in_message') }}
                    </p>
                </div>

                <div class="flex flex-col sm:flex-row gap-3 justify-center">
                    <flux:button
                        href="{{ route('client.consultations.book') }}"
                        variant="primary"
                        class="min-h-[44px]"
                    >
                        <flux:icon name="calendar" class="w-4 h-4 me-2" />
                        {{ __('booking.go_to_dashboard') }}
                    </flux:button>
                </div>

                <p class="mt-6 text-sm text-zinc-500">
                    {{ __('booking.or_logout') }}
                </p>
            </div>
        @else
            @if(session('success'))
                <flux:callout variant="success" class="mb-6">
                    {{ session('success') }}
                </flux:callout>
            @endif

            @if(!$selectedDate || !$selectedTime)
                {{-- Step 1: Calendar Selection --}}
                {{-- Booking Expectations --}}
                <x-booking-expectations class="mb-6" />

                <p class="mb-4 text-zinc-600">
                    {{ __('booking.select_date_time') }}
                </p>

                <livewire:availability-calendar />
            @else
            {{-- Step 2+: Contact Form & Confirmation --}}
            <div class="bg-amber-50 p-4 rounded-lg mb-6 border border-amber-200">
                <div class="flex justify-between items-center">
                    <div>
                        <p class="font-semibold text-zinc-900">
                            {{ __('booking.selected_time') }}
                        </p>
                        <p class="text-zinc-600">
                            {{ \Carbon\Carbon::parse($selectedDate)->translatedFormat('l, d M Y') }}
                        </p>
                        <p class="text-zinc-600">
                            {{ \Carbon\Carbon::parse($selectedTime)->format('g:i A') }}
                        </p>
                    </div>
                    <flux:button size="sm" wire:click="clearSelection">
                        {{ __('common.change') }}
                    </flux:button>
                </div>
            </div>

            @if(!$showConfirmation)
                {{-- Contact Form --}}
                <div class="space-y-4">
                    <flux:field>
                        <flux:label class="required">{{ __('booking.guest_name') }}</flux:label>
                        <flux:input wire:model="guestName" type="text" />
                        <flux:error name="guestName" />
                    </flux:field>

                    <flux:field>
                        <flux:label class="required">{{ __('booking.guest_email') }}</flux:label>
                        <flux:input wire:model="guestEmail" type="email" />
                        <flux:error name="guestEmail" />
                    </flux:field>

                    <flux:field>
                        <flux:label class="required">{{ __('booking.guest_phone') }}</flux:label>
                        <flux:input wire:model="guestPhone" type="tel" />
                        <flux:error name="guestPhone" />
                    </flux:field>

                    <flux:field>
                        <flux:label class="required">{{ __('booking.problem_summary') }}</flux:label>
                        <flux:textarea
                            wire:model="problemSummary"
                            rows="6"
                            placeholder="{{ __('booking.problem_summary_placeholder') }}"
                        />
                        <flux:description>{{ __('booking.problem_summary_help') }}</flux:description>
                        <flux:error name="problemSummary" />
                    </flux:field>

                    {{-- Custom Captcha --}}
                    <flux:field>
                        <flux:label class="required">
                            {{ app()->getLocale() === 'ar' ? $captchaQuestion['question_ar'] : $captchaQuestion['question'] }}
                        </flux:label>
                        <div class="flex gap-2">
                            <flux:input wire:model="captchaAnswer" type="text" class="w-32" />
                            <flux:button size="sm" wire:click="refreshCaptcha" type="button">
                                <flux:icon name="arrow-path" class="w-4 h-4" />
                            </flux:button>
                        </div>
                        <flux:error name="captchaAnswer" />
                    </flux:field>

                    <flux:button
                        wire:click="showConfirm"
                        class="w-full sm:w-auto min-h-[44px]"
                        wire:loading.attr="disabled"
                    >
                        <span wire:loading.remove wire:target="showConfirm">{{ __('booking.continue') }}</span>
                        <span wire:loading wire:target="showConfirm">{{ __('common.loading') }}</span>
                    </flux:button>
                </div>
            @else
                {{-- Confirmation Step --}}
                <flux:callout>
                    <flux:heading size="sm" class="text-body">{{ __('booking.confirm_booking') }}</flux:heading>
                    <p class="text-zinc-600">{{ __('booking.confirm_message') }}</p>

                    <div class="mt-4 space-y-2">
                        <p><strong>{{ __('booking.guest_name') }}:</strong> {{ $guestName }}</p>
                        <p><strong>{{ __('booking.guest_email') }}:</strong> {{ $guestEmail }}</p>
                        <p><strong>{{ __('booking.guest_phone') }}:</strong> {{ $guestPhone }}</p>
                        <p><strong>{{ __('booking.date') }}:</strong>
                            {{ \Carbon\Carbon::parse($selectedDate)->translatedFormat('l, d M Y') }}</p>
                        <p><strong>{{ __('booking.time') }}:</strong>
                            {{ \Carbon\Carbon::parse($selectedTime)->format('g:i A') }}</p>
                        <p><strong>{{ __('booking.duration') }}:</strong> 45 {{ __('common.minutes') }}</p>
                    </div>

                    <div class="mt-4">
                        <p><strong>{{ __('booking.problem_summary') }}:</strong></p>
                        <p class="mt-1 text-sm text-zinc-600">{{ $problemSummary }}</p>
                    </div>
                </flux:callout>

                <div class="flex flex-col sm:flex-row gap-3 mt-4">
                    <flux:button wire:click="$set('showConfirmation', false)" class="w-full sm:w-auto min-h-[44px]">
                        {{ __('common.back') }}
                    </flux:button>
                    <flux:button
                        wire:click="submit"
                        variant="primary"
                        wire:loading.attr="disabled"
                        class="w-full sm:w-auto min-h-[44px]"
                    >
                        <span wire:loading.remove wire:target="submit">{{ __('booking.submit_request') }}</span>
                        <span wire:loading wire:target="submit">{{ __('common.submitting') }}</span>
                    </flux:button>
                </div>

                @error('selectedTime')
                    <flux:callout variant="danger" class="mt-4">
                        {{ $message }}
                    </flux:callout>
                @enderror
            @endif
            @endif
        @endif
</div>
