<?php

use App\Enums\ConsultationStatus;
use App\Models\AdminLog;
use App\Models\BlockedTime;
use App\Models\Consultation;
use Carbon\Carbon;
use Livewire\Volt\Component;

new class extends Component {
    public string $filter = 'upcoming';

    public bool $showModal = false;

    public ?int $editingId = null;

    public string $block_date = '';

    public bool $is_all_day = true;

    public string $start_time = '09:00';

    public string $end_time = '17:00';

    public string $reason = '';

    public array $pendingBookings = [];

    public bool $showDeleteModal = false;

    public ?int $deletingId = null;

    public function mount(): void
    {
        $this->block_date = today()->format('Y-m-d');
    }

    public function openCreateModal(): void
    {
        $this->reset(['editingId', 'block_date', 'is_all_day', 'start_time', 'end_time', 'reason', 'pendingBookings']);
        $this->block_date = today()->format('Y-m-d');
        $this->is_all_day = true;
        $this->start_time = '09:00';
        $this->end_time = '17:00';
        $this->showModal = true;
    }

    public function openEditModal(int $id): void
    {
        $blockedTime = BlockedTime::findOrFail($id);

        $this->editingId = $id;
        $this->block_date = $blockedTime->block_date->format('Y-m-d');
        $this->is_all_day = $blockedTime->isAllDay();
        $this->start_time = $blockedTime->start_time ?? '09:00';
        $this->end_time = $blockedTime->end_time ?? '17:00';
        $this->reason = $blockedTime->reason ?? '';
        $this->pendingBookings = [];
        $this->showModal = true;
    }

    public function closeModal(): void
    {
        $this->showModal = false;
        $this->reset(['editingId', 'pendingBookings']);
        $this->resetValidation();
    }

    public function updatedBlockDate(): void
    {
        $this->checkPendingBookings();
    }

    public function updatedIsAllDay(): void
    {
        $this->checkPendingBookings();
    }

    public function updatedStartTime(): void
    {
        $this->checkPendingBookings();
    }

    public function updatedEndTime(): void
    {
        $this->checkPendingBookings();
    }

    public function checkPendingBookings(): void
    {
        if (empty($this->block_date)) {
            $this->pendingBookings = [];

            return;
        }

        $query = Consultation::query()
            ->whereDate('booking_date', $this->block_date)
            ->where('status', ConsultationStatus::Pending)
            ->with('user:id,full_name,company_name');

        if (! $this->is_all_day && $this->start_time && $this->end_time) {
            $query->where(function ($q) {
                $q->where('booking_time', '>=', $this->start_time)
                    ->where('booking_time', '<', $this->end_time);
            });
        }

        $this->pendingBookings = $query->get()->map(fn ($c) => [
            'id' => $c->id,
            'time' => $c->booking_time,
            'client' => $c->user->full_name ?? $c->user->company_name ?? __('clients.unknown'),
        ])->toArray();
    }

    public function save(): void
    {
        $rules = [
            'block_date' => ['required', 'date'],
            'is_all_day' => ['boolean'],
            'reason' => ['nullable', 'string', 'max:255'],
        ];

        if (! $this->editingId) {
            $rules['block_date'][] = 'after_or_equal:today';
        }

        if (! $this->is_all_day) {
            $rules['start_time'] = ['required'];
            $rules['end_time'] = ['required', 'after:start_time'];
        }

        $this->validate($rules, [
            'block_date.after_or_equal' => __('validation.block_date_future'),
            'end_time.after' => __('validation.end_time_after_start'),
        ]);

        $data = [
            'block_date' => $this->block_date,
            'start_time' => $this->is_all_day ? null : $this->start_time,
            'end_time' => $this->is_all_day ? null : $this->end_time,
            'reason' => $this->reason ?: null,
        ];

        if ($this->editingId) {
            $blockedTime = BlockedTime::findOrFail($this->editingId);
            $oldValues = $blockedTime->toArray();
            $blockedTime->update($data);
            $action = 'update';
        } else {
            $blockedTime = BlockedTime::create($data);
            $oldValues = null;
            $action = 'create';
        }

        AdminLog::create([
            'admin_id' => auth()->id(),
            'action' => $action,
            'target_type' => 'blocked_time',
            'target_id' => $blockedTime->id,
            'old_values' => $oldValues,
            'new_values' => $data,
            'ip_address' => request()->ip(),
            'created_at' => now(),
        ]);

        $this->closeModal();
        session()->flash('success', __('messages.blocked_time_saved'));
    }

    public function confirmDelete(int $id): void
    {
        $this->deletingId = $id;
        $this->showDeleteModal = true;
    }

    public function closeDeleteModal(): void
    {
        $this->showDeleteModal = false;
        $this->deletingId = null;
    }

    public function delete(): void
    {
        $blockedTime = BlockedTime::findOrFail($this->deletingId);

        AdminLog::create([
            'admin_id' => auth()->id(),
            'action' => 'delete',
            'target_type' => 'blocked_time',
            'target_id' => $blockedTime->id,
            'old_values' => $blockedTime->toArray(),
            'new_values' => null,
            'ip_address' => request()->ip(),
            'created_at' => now(),
        ]);

        $blockedTime->delete();

        $this->closeDeleteModal();
        session()->flash('success', __('messages.blocked_time_deleted'));
    }

    public function with(): array
    {
        $query = BlockedTime::query()->orderBy('block_date');

        if ($this->filter === 'upcoming') {
            $query->upcoming();
        } elseif ($this->filter === 'past') {
            $query->past()->orderByDesc('block_date');
        }

        return [
            'blockedTimes' => $query->get(),
        ];
    }
}; ?>

<div>
    <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <div>
            <flux:heading size="xl">{{ __('admin.blocked_times') }}</flux:heading>
            <flux:text class="mt-1 text-zinc-500">
                {{ __('admin.blocked_times_description') }}
            </flux:text>
        </div>
        <flux:button variant="primary" wire:click="openCreateModal" icon="plus">
            {{ __('admin.add_blocked_time') }}
        </flux:button>
    </div>

    @if (session('success'))
        <div class="mb-6">
            <flux:callout variant="success" icon="check-circle">
                {{ session('success') }}
            </flux:callout>
        </div>
    @endif

    {{-- Filter --}}
    <div class="mb-6">
        <flux:select wire:model.live="filter" class="w-48">
            <option value="upcoming">{{ __('admin.upcoming') }}</option>
            <option value="past">{{ __('admin.past') }}</option>
            <option value="all">{{ __('admin.all') }}</option>
        </flux:select>
    </div>

    {{-- List --}}
    <div class="rounded-lg border border-zinc-200 bg-white">
        @forelse($blockedTimes as $blocked)
            <div
                wire:key="blocked-{{ $blocked->id }}"
                class="flex flex-col gap-4 border-b border-zinc-200 p-4 last:border-b-0 sm:flex-row sm:items-center sm:justify-between"
            >
                <div class="flex-1">
                    <div class="flex items-center gap-3">
                        <flux:badge
                            color="{{ $blocked->block_date->isPast() ? 'zinc' : 'amber' }}"
                            size="sm"
                        >
                            {{ $blocked->block_date->format('d/m/Y') }}
                        </flux:badge>

                        @if ($blocked->isAllDay())
                            <flux:badge color="red" size="sm">
                                {{ __('admin.all_day') }}
                            </flux:badge>
                        @else
                            <span class="text-sm text-zinc-600">
                                {{ $blocked->start_time }} - {{ $blocked->end_time }}
                            </span>
                        @endif
                    </div>

                    @if ($blocked->reason)
                        <p class="mt-2 text-sm text-zinc-500">
                            {{ $blocked->reason }}
                        </p>
                    @endif
                </div>

                <div class="flex gap-2">
                    <flux:button size="sm" wire:click="openEditModal({{ $blocked->id }})">
                        {{ __('common.edit') }}
                    </flux:button>
                    <flux:button
                        size="sm"
                        variant="danger"
                        wire:click="confirmDelete({{ $blocked->id }})"
                    >
                        {{ __('common.delete') }}
                    </flux:button>
                </div>
            </div>
        @empty
            <div class="p-8 text-center">
                <flux:icon name="calendar-days" class="mx-auto h-12 w-12 text-zinc-400" />
                <flux:text class="mt-2 text-zinc-500">
                    {{ __('admin.no_blocked_times') }}
                </flux:text>
            </div>
        @endforelse
    </div>

    {{-- Create/Edit Modal --}}
    <flux:modal wire:model="showModal" class="w-full max-w-lg">
        <div class="space-y-6">
            <flux:heading size="lg">
                {{ $editingId ? __('admin.edit_blocked_time') : __('admin.add_blocked_time') }}
            </flux:heading>

            <form wire:submit="save" class="space-y-4">
                <flux:field>
                    <flux:label>{{ __('admin.block_date') }}</flux:label>
                    <flux:input
                        type="date"
                        wire:model.live="block_date"
                        min="{{ $editingId ? '' : today()->format('Y-m-d') }}"
                    />
                    <flux:error name="block_date" />
                </flux:field>

                <flux:field>
                    <div class="flex items-center gap-3">
                        <flux:switch wire:model.live="is_all_day" />
                        <flux:label>{{ __('admin.all_day') }}</flux:label>
                    </div>
                </flux:field>

                @if (! $is_all_day)
                    <div class="grid grid-cols-2 gap-4">
                        <flux:field>
                            <flux:label>{{ __('admin.start_time') }}</flux:label>
                            <flux:input type="time" wire:model.live="start_time" />
                            <flux:error name="start_time" />
                        </flux:field>

                        <flux:field>
                            <flux:label>{{ __('admin.end_time') }}</flux:label>
                            <flux:input type="time" wire:model.live="end_time" />
                            <flux:error name="end_time" />
                        </flux:field>
                    </div>
                @endif

                <flux:field>
                    <flux:label>{{ __('admin.reason') }} ({{ __('common.optional') }})</flux:label>
                    <flux:textarea wire:model="reason" rows="2" />
                    <flux:error name="reason" />
                </flux:field>

                @if (count($pendingBookings) > 0)
                    <flux:callout variant="warning" icon="exclamation-triangle">
                        <flux:text>
                            {{ __('messages.pending_bookings_warning', ['count' => count($pendingBookings)]) }}
                        </flux:text>
                        <ul class="mt-2 list-inside list-disc text-sm">
                            @foreach ($pendingBookings as $booking)
                                <li>{{ $booking['time'] }} - {{ $booking['client'] }}</li>
                            @endforeach
                        </ul>
                    </flux:callout>
                @endif

                <div class="flex justify-end gap-3 pt-4">
                    <flux:button type="button" wire:click="closeModal">
                        {{ __('common.cancel') }}
                    </flux:button>
                    <flux:button type="submit" variant="primary">
                        {{ __('common.save') }}
                    </flux:button>
                </div>
            </form>
        </div>
    </flux:modal>

    {{-- Delete Confirmation Modal --}}
    <flux:modal wire:model="showDeleteModal" class="w-full max-w-md">
        <div class="space-y-6">
            <flux:heading size="lg">{{ __('admin.confirm_delete') }}</flux:heading>
            <flux:text>{{ __('admin.confirm_delete_blocked_time') }}</flux:text>

            <div class="flex justify-end gap-3">
                <flux:button wire:click="closeDeleteModal">
                    {{ __('common.cancel') }}
                </flux:button>
                <flux:button variant="danger" wire:click="delete">
                    {{ __('common.delete') }}
                </flux:button>
            </div>
        </div>
    </flux:modal>
</div>
