<?php

namespace Database\Seeders;

use App\Enums\AccountStatus;
use App\Enums\CustomFieldType;
use App\Enums\EventStatus;
use App\Enums\OrganizerPrimaryEventType;
use App\Enums\TicketCapacityStrategy;
use App\Enums\TicketIac;
use App\Models\Category;
use App\Models\Event;
use App\Models\Organizer;
use App\Models\Role;
use App\Models\TicketType;
use App\Models\User;
use App\Models\Venue;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

/**
 * Evento de prueba de CARRERAS con metadata completo (sport, distancias, tallas, chip, BIB),
 * múltiples distancias (5K / 10K / 21K) y tiers de precio (Promo / Pre-Venta / Regular).
 *
 * Uso: `php artisan db:seed --class=DemoRaceEventSeeder`
 *
 * Idempotente: si el evento ya existe, lo elimina y vuelve a crearlo desde cero.
 */
class DemoRaceEventSeeder extends Seeder
{
    private const SLUG = 'coqui-run-2026-5k-10k-21k';

    private const ORGANIZER_EMAIL = 'organizador-carreras@regiticket.local';

    private const VENUE_SLUG = 'parque-luis-munoz-rivera';

    public function run(): void
    {
        $this->call(DemoCatalogSeeder::class);

        $venue = $this->ensureVenue();
        $category = Category::query()->where('slug', 'carrera')->firstOrFail();
        $organizer = $this->ensureOrganizer();

        Event::query()->where('slug', self::SLUG)->delete();

        $event = $this->createEvent($organizer, $venue, $category);

        $this->createDistanceTickets($event, '5K', 25.00, 30.00, 35.00, 800);
        $this->createDistanceTickets($event, '10K', 30.00, 35.00, 40.00, 600);
        $this->createDistanceTickets($event, '21K', 45.00, 55.00, 65.00, 400);
    }

    private function ensureVenue(): Venue
    {
        return Venue::query()->updateOrCreate(
            ['slug' => self::VENUE_SLUG],
            [
                'name' => 'Parque Luis Muñoz Rivera',
                'address_line_1' => 'Av. Ponce de León',
                'city' => 'San Juan',
                'region' => 'PR',
                'postal_code' => '00907',
                'country' => 'PR',
                'timezone' => 'America/Puerto_Rico',
                'latitude' => 18.4636,
                'longitude' => -66.0875,
                'metadata' => [
                    'amenities' => ['estacionamiento', 'baños públicos', 'fuentes de agua'],
                    'access_notes' => 'Punto de salida y meta en la entrada principal.',
                ],
            ]
        );
    }

    private function ensureOrganizer(): Organizer
    {
        $user = User::query()->updateOrCreate(
            ['email' => self::ORGANIZER_EMAIL],
            [
                'name' => 'Coquí Running Club',
                'password' => Hash::make('password'),
                'role_id' => Role::query()->where('slug', Role::SLUG_ORGANIZADOR)->value('id'),
                'account_status' => AccountStatus::Approved,
                'organization_name' => 'Coquí Running Club',
                'phone' => '+1 787-555-0142',
                'email_verified_at' => now(),
            ]
        );

        return Organizer::query()->updateOrCreate(
            ['user_id' => $user->id],
            [
                'paypal_email' => self::ORGANIZER_EMAIL,
                'primary_event_type' => OrganizerPrimaryEventType::Race,
            ]
        );
    }

    private function createEvent(Organizer $organizer, Venue $venue, Category $category): Event
    {
        $start = Carbon::parse('2026-09-12 06:00:00', 'America/Puerto_Rico');
        $end = $start->copy()->addHours(5);

        $metadata = [
            'primary_type' => 'race',
            'sport' => [
                'enabled' => true,
                'distances' => ['5K', '10K', '21K'],
                'bib_assignment' => 'auto_sequential',
                'bib' => [
                    'start_number' => 100,
                    'end_number' => 1999,
                    'padding' => 4,
                    // Caso real: el organizador vendió presencialmente del 1 al 50 antes de abrir la web,
                    // y reservó 75 para el patrocinador y 90-99 para staff/voluntarios.
                    'reserved' => '1-50, 75, 90-99',
                    'reserved_parsed' => \App\Support\BibRangeParser::parse('1-50, 75, 90-99'),
                ],
                'chip_timing' => 'disposable',
                'route_type' => 'road',
                'time_limit' => '180',
                'age_groups' => "Juvenil (15-19)\nOpen (20-29)\nMaster A (30-39)\nMaster B (40-49)\nMaster C (50-59)\nVeteranos (60+)",
                'tallas' => [
                    'enabled' => true,
                    'sizes' => ['XS', 'S', 'M', 'L', 'XL', '2XL'],
                    'cut' => 'dama_caballero',
                ],
            ],
        ];

        $eventAttrs = [
            'organizer_id' => $organizer->id,
            'venue_id' => $venue->id,
            'category_id' => $category->id,
            'title' => 'Coquí Run 2026 — 5K, 10K y 21K',
            'description' => '<p>La <strong>Coquí Run 2026</strong> regresa con tres distancias certificadas en el corazón de San Juan. Recorre la Avenida Ponce de León con vista al Capitolio y la costa, con cronometraje por chip desechable y medalla finisher para todas las distancias.</p>'
                .'<ul><li>Camisa técnica oficial Dri-Fit</li><li>Medalla conmemorativa</li><li>Hidratación cada 2K</li><li>Resultados en línea en tiempo real</li><li>Premiación por categoría de edad</li></ul>'
                .'<p><em>Cierre del curso: 3 horas (180 min). Ruta certificada AIMS.</em></p>',
            'short_description' => 'Carrera certificada de 5K, 10K y 21K por la Av. Ponce de León. Chip cronometraje, medalla finisher y camisa técnica para todos los participantes.',
            'start_date' => $start,
            'end_date' => $end,
            'timezone' => 'America/Puerto_Rico',
            'status' => EventStatus::Published,
            'metadata' => $metadata,
        ];

        if (Schema::hasColumn('events', 'hide_from_listings')) {
            $eventAttrs['hide_from_listings'] = false;
            $eventAttrs['sticky_in_calendar'] = true;
            $eventAttrs['is_featured'] = true;
        }

        return Event::query()->create(array_merge($eventAttrs, ['slug' => self::SLUG]));
    }

    /**
     * Crea 3 tiers de precio (Promo Lanzamiento, Pre-Venta, Regular) para una distancia,
     * cada tier comparte el cupo via shared_pool_size + custom fields IAC para corredores.
     */
    private function createDistanceTickets(
        Event $event,
        string $distance,
        float $promoPrice,
        float $preventaPrice,
        float $regularPrice,
        int $sharedPool,
    ): void {
        $now = Carbon::now();
        $eventStart = $event->start_date;

        $tiers = [
            [
                'name' => "{$distance} — Promo Lanzamiento",
                'description' => 'Cupo limitado al primer 20% del bloque. ¡Asegura tu plaza al mejor precio!',
                'price' => $promoPrice + 5,
                'sale_price' => $promoPrice,
                'sale_start' => $now->copy()->subWeek(),
                'sale_end' => $now->copy()->addDays(14),
                'sku' => "COQUI26-{$distance}-PROMO",
            ],
            [
                'name' => "{$distance} — Pre-Venta",
                'description' => 'Precio anticipado hasta 30 días antes del evento.',
                'price' => $preventaPrice,
                'sale_price' => null,
                'sale_start' => $now->copy()->addDays(15),
                'sale_end' => $eventStart->copy()->subMonth(),
                'sku' => "COQUI26-{$distance}-PRE",
            ],
            [
                'name' => "{$distance} — Regular",
                'description' => 'Inscripción a precio regular hasta cierre.',
                'price' => $regularPrice,
                'sale_price' => null,
                'sale_start' => $eventStart->copy()->subMonth()->addDay(),
                'sale_end' => $eventStart->copy()->subDay(),
                'sku' => "COQUI26-{$distance}-REG",
            ],
        ];

        foreach ($tiers as $tier) {
            $ticket = TicketType::query()->create([
                'event_id' => $event->id,
                'name' => $tier['name'],
                'description' => $tier['description'],
                'price' => $tier['price'],
                'sale_price' => $tier['sale_price'],
                'currency' => 'USD',
                'sku' => $tier['sku'],
                'capacity_strategy' => TicketCapacityStrategy::SharedPool,
                'capacity' => $sharedPool,
                'shared_pool_size' => $sharedPool,
                'quantity_sold' => 0,
                'is_active' => true,
                'sale_start' => $tier['sale_start'],
                'sale_end' => $tier['sale_end'],
                'iac' => TicketIac::Required,
                'ticket_kind' => 'standard',
            ]);

            $this->attachRunnerCustomFields($ticket, $distance);
        }
    }

    private function attachRunnerCustomFields(TicketType $ticket, string $distance): void
    {
        $fields = [
            [
                'label' => 'Fecha de nacimiento',
                'slug' => 'fecha-nacimiento',
                'type' => CustomFieldType::Text,
                'options' => null,
                'required' => true,
                'sort_order' => 0,
            ],
            [
                'label' => 'Género',
                'slug' => 'genero',
                'type' => CustomFieldType::Select,
                'options' => ['Femenino', 'Masculino', 'No binario'],
                'required' => true,
                'sort_order' => 1,
            ],
            [
                'label' => 'Talla de camisa',
                'slug' => 'talla-camisa',
                'type' => CustomFieldType::Select,
                'options' => ['XS', 'S', 'M', 'L', 'XL', '2XL'],
                'required' => true,
                'sort_order' => 2,
            ],
            [
                'label' => 'Nacionalidad',
                'slug' => 'nacionalidad',
                'type' => CustomFieldType::Text,
                'options' => null,
                'required' => true,
                'sort_order' => 3,
            ],
            [
                'label' => 'Club o equipo',
                'slug' => 'club-equipo',
                'type' => CustomFieldType::Text,
                'options' => null,
                'required' => false,
                'sort_order' => 4,
            ],
            [
                'label' => 'Categoría de competencia',
                'slug' => 'categoria-competencia',
                'type' => CustomFieldType::Select,
                'options' => ['Elite', 'Age Group', 'Recreativo'],
                'required' => true,
                'sort_order' => 5,
            ],
            [
                'label' => "Mejor tiempo previo en {$distance} (opcional, formato HH:MM:SS)",
                'slug' => 'mejor-tiempo-'.Str::slug($distance),
                'type' => CustomFieldType::Text,
                'options' => null,
                'required' => false,
                'sort_order' => 6,
            ],
            [
                'label' => 'Contacto de emergencia (nombre y teléfono)',
                'slug' => 'contacto-emergencia',
                'type' => CustomFieldType::Text,
                'options' => null,
                'required' => true,
                'sort_order' => 7,
            ],
            [
                'label' => 'Acepto reglamento, descargo de responsabilidad y reglas de la carrera',
                'slug' => 'acepto-reglamento',
                'type' => CustomFieldType::Checkbox,
                'options' => null,
                'required' => true,
                'sort_order' => 8,
            ],
        ];

        foreach ($fields as $field) {
            $ticket->customFields()->create($field);
        }
    }
}
