<?php

namespace App\Livewire;

use App\Models\Park;
use App\Models\Operator;
use App\Enums\ParkStatus;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Validation\Rules\Enum;

class ParkFormComponent extends Component
{
    use WithFileUploads;

    public ?Park $park = null;
    
    // Form fields
    public string $name = '';
    public ?string $description = '';
    public string $status = '';
    public ?string $opening_date = '';
    public ?string $closing_date = '';
    public ?string $operating_season = '';
    public ?string $size_acres = '';
    public ?string $website = '';
    public ?int $operator_id = null;

    /** @var array<string> */
    public array $statusOptions = [];

    /** @var array<array-key, array<string, string>> */
    public array $operators = [];

    public function mount(?Park $park = null): void
    {
        $this->park = $park;
        
        if ($park) {
            $this->name = $park->name;
            $this->description = $park->description ?? '';
            $this->status = $park->status->value;
            $this->opening_date = $park->opening_date?->format('Y-m-d') ?? '';
            $this->closing_date = $park->closing_date?->format('Y-m-d') ?? '';
            $this->operating_season = $park->operating_season ?? '';
            $this->size_acres = $park->size_acres ? (string)$park->size_acres : '';
            $this->website = $park->website ?? '';
            $this->operator_id = $park->operator_id;
        } else {
            $this->status = ParkStatus::OPERATING->value;
        }

        // Load status options
        $this->statusOptions = collect(ParkStatus::cases())
            ->mapWithKeys(fn (ParkStatus $status) => [$status->value => $status->label()])
            ->toArray();

        // Load operators for select
        $this->operators = Operator::orderBy('name')
            ->get(['id', 'name'])
            ->map(fn ($operator) => ['id' => $operator->id, 'name' => $operator->name])
            ->toArray();
    }

    public function rules(): array
    {
        $unique = $this->park 
            ? "unique:parks,name,{$this->park->id}"
            : 'unique:parks,name';

        return [
            'name' => ['required', 'string', 'min:2', 'max:255', $unique],
            'description' => ['nullable', 'string'],
            'status' => ['required', new Enum(ParkStatus::class)],
            'opening_date' => ['nullable', 'date'],
            'closing_date' => ['nullable', 'date', 'after:opening_date'],
            'operating_season' => ['nullable', 'string', 'max:255'],
            'size_acres' => ['nullable', 'numeric', 'min:0', 'max:999999.99'],
            'website' => ['nullable', 'url', 'max:255'],
            'operator_id' => ['nullable', 'exists:operators,id'],
        ];
    }

    public function save(): void
    {
        $data = $this->validate();

        if ($this->park) {
            $this->park->update($data);
            $message = 'Park updated successfully!';
        } else {
            $this->park = Park::create($data);
            $message = 'Park created successfully!';
        }

        session()->flash('message', $message);
        
        $this->redirectRoute('parks.show', $this->park);
    }

    public function render()
    {
        return view('livewire.park-form-component');
    }
}