<?php

use App\Enums\EventType;
use App\Enums\GeneralType;
use App\Enums\JourneyMethod;
use App\Enums\TravelStatus;
use App\Models\ApprovalWorkflow;
use App\Models\EmergencyContact;
use App\Models\TravelCostCode;
use App\Models\TravelJourney;
use App\Models\TravelRequest;
use App\Services\ApprovalService;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Validate;
use Livewire\Component;

new #[Layout('components.layouts.app')] class extends Component {
    // Emergency Contact
    public string $emergencyFullName = '';
    public string $emergencyPhone = '';
    public string $emergencyRelationship = '';

    // Reason for travel
    public string $reasonSummary = '';
    public string $travelCategory = 'event'; // 'event' or 'general'
    public string $eventType = '';
    public string $generalType = '';

    // Journeys - array of rows
    /** @var array<int, array<string, string>> */
    public array $journeys = [];

    // Additional details
    public bool $needsAccommodation = false;
    public bool $needsCarHire = false;
    public bool $vehiclePolicyAcknowledged = false;
    public int $businessDays = 0;
    public int $privateDays = 0;
    public string $additionalNotes = '';

    // Cost codes - array of rows
    /** @var array<int, array<string, string>> */
    public array $costCodes = [];

    public function mount(): void
    {
        $user = Auth::user();
        $contact = $user->emergencyContacts()->first();

        if ($contact) {
            $this->emergencyFullName = $contact->full_name;
            $this->emergencyPhone = $contact->phone_number;
            $this->emergencyRelationship = $contact->relationship;
        }

        $this->addJourney();
        $this->addCostCode();
    }

    public function addJourney(): void
    {
        $this->journeys[] = [
            'origin' => '',
            'destination' => '',
            'date' => '',
            'time' => '',
            'method' => JourneyMethod::Air->value,
        ];
    }

    public function removeJourney(int $index): void
    {
        array_splice($this->journeys, $index, 1);
    }

    public function addCostCode(): void
    {
        $this->costCodes[] = [
            'business_unit' => '',
            'project_grant' => '',
            'account_code' => '',
            'class_code' => '',
        ];
    }

    public function removeCostCode(int $index): void
    {
        array_splice($this->costCodes, $index, 1);
    }

    public function saveDraft(): void
    {
        $this->saveRequest(submit: false);
        session()->flash('success', 'Draft saved successfully.');
    }

    public function submit(): void
    {
        $this->saveRequest(submit: true);
    }

    private function saveRequest(bool $submit): void
    {
        $this->validate([
            'emergencyFullName' => ['required', 'string', 'max:255'],
            'emergencyPhone' => ['required', 'string', 'max:50'],
            'emergencyRelationship' => ['required', 'string', 'max:100'],
            'reasonSummary' => ['required', 'string', 'min:10'],
            'journeys' => ['required', 'array', 'min:1'],
            'journeys.*.origin' => ['required', 'string', 'max:255'],
            'journeys.*.destination' => ['required', 'string', 'max:255'],
            'journeys.*.date' => ['required', 'date'],
            'journeys.*.method' => ['required', 'string'],
            'costCodes' => ['array'],
            'vehiclePolicyAcknowledged' => $this->needsCarHire ? ['accepted'] : [],
        ], [
            'emergencyFullName.required' => 'Emergency contact name is required.',
            'emergencyPhone.required' => 'Emergency contact phone is required.',
            'emergencyRelationship.required' => 'Emergency contact relationship is required.',
            'reasonSummary.required' => 'Please provide a reason for travel.',
            'reasonSummary.min' => 'Reason must be at least 10 characters.',
            'journeys.required' => 'At least one journey is required.',
            'journeys.*.origin.required' => 'Origin is required for each journey.',
            'journeys.*.destination.required' => 'Destination is required for each journey.',
            'journeys.*.date.required' => 'Date is required for each journey.',
            'vehiclePolicyAcknowledged.accepted' => 'You must acknowledge the vehicle policy when hiring a car.',
        ]);

        $user = Auth::user();

        // Save emergency contact
        $user->emergencyContacts()->updateOrCreate(
            ['user_id' => $user->id],
            [
                'full_name' => $this->emergencyFullName,
                'phone_number' => $this->emergencyPhone,
                'relationship' => $this->emergencyRelationship,
            ]
        );

        $workflow = ApprovalWorkflow::where('is_active', true)->first();

        $travelRequest = TravelRequest::create([
            'user_id' => $user->id,
            'workflow_id' => $workflow?->id,
            'status' => TravelStatus::Draft,
            'reason_summary' => $this->reasonSummary,
            'event_type' => $this->travelCategory === 'event' && $this->eventType ? $this->eventType : null,
            'general_type' => $this->travelCategory === 'general' && $this->generalType ? $this->generalType : null,
            'needs_accommodation' => $this->needsAccommodation,
            'needs_car_hire' => $this->needsCarHire,
            'vehicle_policy_acknowledged' => $this->vehiclePolicyAcknowledged,
            'business_days' => $this->businessDays,
            'private_days' => $this->privateDays,
            'additional_notes' => $this->additionalNotes ?: null,
        ]);

        foreach ($this->journeys as $journey) {
            TravelJourney::create([
                'travel_request_id' => $travelRequest->id,
                'origin' => $journey['origin'],
                'destination' => $journey['destination'],
                'date' => $journey['date'],
                'time' => $journey['time'] ?: null,
                'method' => $journey['method'],
            ]);
        }

        foreach ($this->costCodes as $code) {
            if (array_filter($code)) {
                TravelCostCode::create([
                    'travel_request_id' => $travelRequest->id,
                    'business_unit' => $code['business_unit'] ?: null,
                    'project_grant' => $code['project_grant'] ?: null,
                    'account_code' => $code['account_code'] ?: null,
                    'class_code' => $code['class_code'] ?: null,
                ]);
            }
        }

        if ($submit) {
            app(ApprovalService::class)->submit($travelRequest);
            session()->flash('success', 'Travel request submitted for approval.');
        }

        $this->redirect(route('travel-requests.show', $travelRequest), navigate: true);
    }

    public function render(): mixed
    {
        return view('livewire.travel-request.create', [
            'user' => Auth::user(),
            'journeyMethods' => JourneyMethod::cases(),
            'eventTypes' => EventType::cases(),
            'generalTypes' => GeneralType::cases(),
        ]);
    }
}
?>

<div>
    <h2 class="h4 mb-4">New Travel Request</h2>

    @if (session('success'))
        <div class="alert alert-success alert-dismissible fade show">
            {{ session('success') }}
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        </div>
    @endif

    <form wire:submit.prevent>

        {{-- Applicant Details --}}
        <div class="card mb-4">
            <div class="card-header fw-semibold">Applicant Details</div>
            <div class="card-body">
                <div class="row g-3">
                    <div class="col-md-6">
                        <label class="form-label">Name</label>
                        <input type="text" class="form-control" value="{{ $user->name }}" readonly>
                    </div>
                    <div class="col-md-6">
                        <label class="form-label">Email</label>
                        <input type="email" class="form-control" value="{{ $user->email }}" readonly>
                    </div>
                    <div class="col-md-6">
                        <label class="form-label">Department</label>
                        <input type="text" class="form-control" value="{{ $user->department ?? '—' }}" readonly>
                    </div>
                    <div class="col-md-6">
                        <label class="form-label">Title</label>
                        <input type="text" class="form-control" value="{{ $user->title ?? '—' }}" readonly>
                    </div>
                </div>
            </div>
        </div>

        {{-- Emergency Contact --}}
        <div class="card mb-4">
            <div class="card-header fw-semibold">Emergency Contact</div>
            <div class="card-body">
                <div class="row g-3">
                    <div class="col-md-4">
                        <label class="form-label">Full Name <span class="text-danger">*</span></label>
                        <input type="text" wire:model="emergencyFullName" class="form-control @error('emergencyFullName') is-invalid @enderror">
                        @error('emergencyFullName') <div class="invalid-feedback">{{ $message }}</div> @enderror
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Phone Number <span class="text-danger">*</span></label>
                        <input type="text" wire:model="emergencyPhone" class="form-control @error('emergencyPhone') is-invalid @enderror">
                        @error('emergencyPhone') <div class="invalid-feedback">{{ $message }}</div> @enderror
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Relationship <span class="text-danger">*</span></label>
                        <input type="text" wire:model="emergencyRelationship" class="form-control @error('emergencyRelationship') is-invalid @enderror">
                        @error('emergencyRelationship') <div class="invalid-feedback">{{ $message }}</div> @enderror
                    </div>
                </div>
            </div>
        </div>

        {{-- Reasons for Travel --}}
        <div class="card mb-4">
            <div class="card-header fw-semibold">Reasons for Travel</div>
            <div class="card-body">
                <div class="mb-3">
                    <label class="form-label">Reason Summary <span class="text-danger">*</span></label>
                    <textarea wire:model="reasonSummary" rows="3" class="form-control @error('reasonSummary') is-invalid @enderror" placeholder="Briefly describe the purpose of this travel..."></textarea>
                    @error('reasonSummary') <div class="invalid-feedback">{{ $message }}</div> @enderror
                </div>

                <div class="mb-3">
                    <label class="form-label">Travel Category</label>
                    <div class="d-flex gap-4">
                        <div class="form-check">
                            <input type="radio" id="categoryEvent" wire:model.live="travelCategory" value="event" class="form-check-input">
                            <label for="categoryEvent" class="form-check-label">Event Specific</label>
                        </div>
                        <div class="form-check">
                            <input type="radio" id="categoryGeneral" wire:model.live="travelCategory" value="general" class="form-check-input">
                            <label for="categoryGeneral" class="form-check-label">General</label>
                        </div>
                    </div>
                </div>

                @if ($travelCategory === 'event')
                    <div class="mb-3">
                        <label class="form-label">Event Type</label>
                        <select wire:model="eventType" class="form-select">
                            <option value="">Select event type...</option>
                            @foreach ($eventTypes as $type)
                                <option value="{{ $type->value }}">{{ $type->label() }}</option>
                            @endforeach
                        </select>
                    </div>
                @else
                    <div class="mb-3">
                        <label class="form-label">General Type</label>
                        <select wire:model="generalType" class="form-select">
                            <option value="">Select type...</option>
                            @foreach ($generalTypes as $type)
                                <option value="{{ $type->value }}">{{ $type->label() }}</option>
                            @endforeach
                        </select>
                    </div>
                @endif
            </div>
        </div>

        {{-- Journeys --}}
        <div class="card mb-4" x-data="{
            stateFilter: '',
            suggestions: {},
            open: {},
            async searchTowns(key, query) {
                if (query.length < 2) {
                    this.suggestions[key] = [];
                    this.open[key] = false;
                    return;
                }
                const params = new URLSearchParams({ query });
                if (this.stateFilter) params.append('state', this.stateFilter);
                const res = await fetch(`/towns/search?${params}`, {
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });
                const data = await res.json();
                this.suggestions[key] = data;
                this.open[key] = data.length > 0;
            },
            selectTown(key, wirePath, name) {
                $wire.set(wirePath, name);
                this.suggestions[key] = [];
                this.open[key] = false;
            }
        }">
            <div class="card-header fw-semibold d-flex justify-content-between align-items-center">
                <span>Journeys</span>
                <div class="d-flex align-items-center gap-2">
                    <select x-model="stateFilter" class="form-select form-select-sm" style="width: auto;" title="Filter town autocomplete by state">
                        <option value="">All states</option>
                        @foreach(\App\Enums\AustralianState::cases() as $state)
                            <option value="{{ $state->value }}">{{ $state->abbreviation() }}</option>
                        @endforeach
                    </select>
                    <button type="button" wire:click="addJourney" class="btn btn-sm btn-outline-primary">+ Add Journey</button>
                </div>
            </div>
            <div class="card-body">
                @error('journeys') <div class="alert alert-danger">{{ $message }}</div> @enderror

                @foreach ($journeys as $i => $journey)
                    <div class="border rounded p-3 mb-3" wire:key="journey-{{ $i }}">
                        <div class="d-flex justify-content-between align-items-center mb-2">
                            <strong class="small">Journey {{ $i + 1 }}</strong>
                            @if (count($journeys) > 1)
                                <button type="button" wire:click="removeJourney({{ $i }})" class="btn btn-sm btn-outline-danger">Remove</button>
                            @endif
                        </div>
                        <div class="row g-3">
                            <div class="col-md-3">
                                <label class="form-label">Origin <span class="text-danger">*</span></label>
                                <div class="position-relative">
                                    <input
                                        type="text"
                                        wire:model="journeys.{{ $i }}.origin"
                                        class="form-control @error('journeys.'.$i.'.origin') is-invalid @enderror"
                                        placeholder="e.g. Perth"
                                        autocomplete="off"
                                        x-on:input.debounce.300ms="searchTowns('{{ $i }}-origin', $event.target.value)"
                                        x-on:blur="$nextTick(() => open['{{ $i }}-origin'] = false)"
                                    >
                                    <ul class="dropdown-menu w-100" x-show="open['{{ $i }}-origin'] ?? false" style="z-index: 1055;">
                                        <template x-for="s in (suggestions['{{ $i }}-origin'] ?? [])">
                                            <li>
                                                <button type="button" class="dropdown-item small"
                                                    x-text="s.label"
                                                    x-on:mousedown.prevent="selectTown('{{ $i }}-origin', 'journeys.{{ $i }}.origin', s.name)"
                                                ></button>
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                                @error('journeys.'.$i.'.origin') <div class="invalid-feedback d-block">{{ $message }}</div> @enderror
                            </div>
                            <div class="col-md-3">
                                <label class="form-label">Destination <span class="text-danger">*</span></label>
                                <div class="position-relative">
                                    <input
                                        type="text"
                                        wire:model="journeys.{{ $i }}.destination"
                                        class="form-control @error('journeys.'.$i.'.destination') is-invalid @enderror"
                                        placeholder="e.g. Sydney"
                                        autocomplete="off"
                                        x-on:input.debounce.300ms="searchTowns('{{ $i }}-destination', $event.target.value)"
                                        x-on:blur="$nextTick(() => open['{{ $i }}-destination'] = false)"
                                    >
                                    <ul class="dropdown-menu w-100" x-show="open['{{ $i }}-destination'] ?? false" style="z-index: 1055;">
                                        <template x-for="s in (suggestions['{{ $i }}-destination'] ?? [])">
                                            <li>
                                                <button type="button" class="dropdown-item small"
                                                    x-text="s.label"
                                                    x-on:mousedown.prevent="selectTown('{{ $i }}-destination', 'journeys.{{ $i }}.destination', s.name)"
                                                ></button>
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                                @error('journeys.'.$i.'.destination') <div class="invalid-feedback d-block">{{ $message }}</div> @enderror
                            </div>
                            <div class="col-md-2">
                                <label class="form-label">Date <span class="text-danger">*</span></label>
                                <input type="date" wire:model="journeys.{{ $i }}.date" class="form-control @error('journeys.'.$i.'.date') is-invalid @enderror">
                                @error('journeys.'.$i.'.date') <div class="invalid-feedback">{{ $message }}</div> @enderror
                            </div>
                            <div class="col-md-2">
                                <label class="form-label">Time</label>
                                <input type="time" wire:model="journeys.{{ $i }}.time" class="form-control">
                            </div>
                            <div class="col-md-2">
                                <label class="form-label">Method</label>
                                <select wire:model="journeys.{{ $i }}.method" class="form-select">
                                    @foreach ($journeyMethods as $method)
                                        <option value="{{ $method->value }}">{{ $method->label() }}</option>
                                    @endforeach
                                </select>
                            </div>
                        </div>
                    </div>
                @endforeach
            </div>
        </div>

        {{-- Additional Details --}}
        <div class="card mb-4">
            <div class="card-header fw-semibold">Additional Details</div>
            <div class="card-body">
                <div class="row g-3 mb-3">
                    <div class="col-auto">
                        <div class="form-check">
                            <input type="checkbox" id="needsAccommodation" wire:model="needsAccommodation" class="form-check-input">
                            <label for="needsAccommodation" class="form-check-label">Requires Accommodation</label>
                        </div>
                    </div>
                    <div class="col-auto">
                        <div class="form-check">
                            <input type="checkbox" id="needsCarHire" wire:model.live="needsCarHire" class="form-check-input">
                            <label for="needsCarHire" class="form-check-label">Requires Car Hire</label>
                        </div>
                    </div>
                    @if ($needsCarHire)
                        <div class="col-12">
                            <div class="form-check">
                                <input type="checkbox" id="vehiclePolicy" wire:model="vehiclePolicyAcknowledged" class="form-check-input @error('vehiclePolicyAcknowledged') is-invalid @enderror">
                                <label for="vehiclePolicy" class="form-check-label">I have read and acknowledge the RCSWA Vehicle Use Policy</label>
                                @error('vehiclePolicyAcknowledged') <div class="invalid-feedback">{{ $message }}</div> @enderror
                            </div>
                        </div>
                    @endif
                </div>

                <div class="row g-3 mb-3">
                    <div class="col-md-3">
                        <label class="form-label">Business Days</label>
                        <input type="number" wire:model="businessDays" class="form-control" min="0" max="365">
                    </div>
                    <div class="col-md-3">
                        <label class="form-label">Private Days</label>
                        <input type="number" wire:model="privateDays" class="form-control" min="0" max="365">
                    </div>
                </div>

                <div>
                    <label class="form-label">Additional Notes</label>
                    <textarea wire:model="additionalNotes" rows="2" class="form-control" placeholder="Any additional information..."></textarea>
                </div>
            </div>
        </div>

        {{-- Cost Codes --}}
        <div class="card mb-4">
            <div class="card-header fw-semibold d-flex justify-content-between align-items-center">
                Cost Codes
                <button type="button" wire:click="addCostCode" class="btn btn-sm btn-outline-primary">+ Add Cost Code</button>
            </div>
            <div class="card-body">
                @foreach ($costCodes as $i => $code)
                    <div class="border rounded p-3 mb-3" wire:key="code-{{ $i }}">
                        <div class="d-flex justify-content-between align-items-center mb-2">
                            <strong class="small">Cost Code {{ $i + 1 }}</strong>
                            @if (count($costCodes) > 1)
                                <button type="button" wire:click="removeCostCode({{ $i }})" class="btn btn-sm btn-outline-danger">Remove</button>
                            @endif
                        </div>
                        <div class="row g-3">
                            <div class="col-md-3">
                                <label class="form-label">Business Unit</label>
                                <input type="text" wire:model="costCodes.{{ $i }}.business_unit" class="form-control">
                            </div>
                            <div class="col-md-3">
                                <label class="form-label">Project/Grant</label>
                                <input type="text" wire:model="costCodes.{{ $i }}.project_grant" class="form-control">
                            </div>
                            <div class="col-md-3">
                                <label class="form-label">Account Code</label>
                                <input type="text" wire:model="costCodes.{{ $i }}.account_code" class="form-control">
                            </div>
                            <div class="col-md-3">
                                <label class="form-label">Class Code</label>
                                <input type="text" wire:model="costCodes.{{ $i }}.class_code" class="form-control">
                            </div>
                        </div>
                    </div>
                @endforeach
            </div>
        </div>

        {{-- Actions --}}
        <div class="d-flex gap-2">
            <button type="button" wire:click="saveDraft" class="btn btn-outline-secondary" wire:loading.attr="disabled">
                <span wire:loading wire:target="saveDraft" class="spinner-border spinner-border-sm me-1"></span>
                Save Draft
            </button>
            <button type="button" wire:click="submit" class="btn btn-primary" wire:loading.attr="disabled">
                <span wire:loading wire:target="submit" class="spinner-border spinner-border-sm me-1"></span>
                Submit for Approval
            </button>
        </div>

    </form>
</div>
