-- Ticket system migration for match ticketing
-- Migration: 20250109000001_add_ticket_system.up.sql

-- Enable UUID extension if not exists
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Ticket types for different pricing tiers
CREATE TABLE ticket_types (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE,
    
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price_cents BIGINT NOT NULL,
    currency VARCHAR(10) DEFAULT 'CZK',
    color VARCHAR(20) DEFAULT 'primary', -- primary, secondary, success, warning, danger
    display_order INTEGER DEFAULT 0,
    active BOOLEAN DEFAULT true,
    
    -- Constraints and limits
    max_tickets_per_order INTEGER DEFAULT 10,
    sale_start_time TIMESTAMP WITH TIME ZONE,
    sale_end_time TIMESTAMP WITH TIME ZONE,
    
    -- Access control (optional)
    requires_membership BOOLEAN DEFAULT false,
    min_age INTEGER,
    
    INDEX idx_ticket_types_active (active),
    INDEX idx_ticket_types_order (display_order)
);

-- Ticket campaigns for specific matches or events
CREATE TABLE ticket_campaigns (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE,
    
    title VARCHAR(255) NOT NULL,
    description TEXT,
    
    -- Link to match (can be null for non-match events)
    external_match_id VARCHAR(255), -- FACR match ID
    competition_code VARCHAR(50),
    match_date_time TIMESTAMP WITH TIME ZONE,
    home_team VARCHAR(255),
    away_team VARCHAR(255),
    venue VARCHAR(255),
    
    -- Campaign settings
    active BOOLEAN DEFAULT true,
    sale_start_time TIMESTAMP WITH TIME ZONE NOT NULL,
    sale_end_time TIMESTAMP WITH TIME ZONE NOT NULL,
    max_total_tickets INTEGER, -- Overall capacity limit
    
    INDEX idx_ticket_campaigns_active (active),
    INDEX idx_ticket_campaigns_match (external_match_id),
    INDEX idx_ticket_campaigns_dates (sale_start_time, sale_end_time)
);

-- Link ticket types to campaigns (many-to-many with campaign-specific overrides)
CREATE TABLE campaign_ticket_types (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    
    campaign_id UUID NOT NULL REFERENCES ticket_campaigns(id) ON DELETE CASCADE,
    ticket_type_id UUID NOT NULL REFERENCES ticket_types(id) ON DELETE CASCADE,
    
    -- Campaign-specific overrides
    price_cents BIGINT, -- Override default price if set
    max_quantity INTEGER, -- Campaign-specific quantity limit
    
    UNIQUE(campaign_id, ticket_type_id),
    INDEX idx_campaign_ticket_types_campaign (campaign_id),
    INDEX idx_campaign_ticket_types_type (ticket_type_id)
);

-- Ticket instances (actual sold tickets)
CREATE TABLE tickets (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    
    order_id UUID, -- Link to e-shop order when purchased
    campaign_id UUID NOT NULL REFERENCES ticket_campaigns(id),
    ticket_type_id UUID NOT NULL REFERENCES ticket_types(id),
    
    -- Ticket holder information
    holder_name VARCHAR(255) NOT NULL,
    holder_email VARCHAR(255) NOT NULL,
    holder_phone VARCHAR(50),
    
    -- Ticket details
    quantity INTEGER NOT NULL DEFAULT 1,
    unit_price_cents BIGINT NOT NULL,
    total_price_cents BIGINT NOT NULL,
    currency VARCHAR(10) DEFAULT 'CZK',
    
    -- Status tracking
    status VARCHAR(20) DEFAULT 'reserved', -- reserved, paid, cancelled, used
    barcode VARCHAR(255) UNIQUE, -- Unique barcode/QR code
    qr_code_data TEXT, -- JSON with QR code data
    
    -- Usage tracking
    used_at TIMESTAMP WITH TIME ZONE,
    used_by VARCHAR(255), -- Who validated the ticket
    
    INDEX idx_tickets_order (order_id),
    INDEX idx_tickets_campaign (campaign_id),
    INDEX idx_tickets_status (status),
    INDEX idx_tickets_barcode (barcode),
    INDEX idx_tickets_holder_email (holder_email)
);

-- Ticket availability tracking per campaign/type
CREATE TABLE ticket_availability (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    
    campaign_id UUID NOT NULL REFERENCES ticket_campaigns(id) ON DELETE CASCADE,
    ticket_type_id UUID NOT NULL REFERENCES ticket_types(id) ON DELETE CASCADE,
    
    total_capacity INTEGER NOT NULL DEFAULT 0,
    sold_quantity INTEGER NOT NULL DEFAULT 0,
    reserved_quantity INTEGER NOT NULL DEFAULT 0,
    available_quantity INTEGER GENERATED ALWAYS AS (total_capacity - sold_quantity - reserved_quantity) STORED,
    
    UNIQUE(campaign_id, ticket_type_id),
    INDEX idx_ticket_availability_campaign (campaign_id),
    INDEX idx_ticket_availability_type (ticket_type_id)
);

-- Add ticket-related fields to existing e-shop orders
ALTER TABLE eshop_orders 
ADD COLUMN ticket_order BOOLEAN DEFAULT false,
ADD COLUMN ticket_campaign_id UUID REFERENCES ticket_campaigns(id);

-- Create indexes for new order fields
CREATE INDEX idx_eshop_orders_ticket_order ON eshop_orders(ticket_order);
CREATE INDEX idx_eshop_orders_ticket_campaign ON eshop_orders(ticket_campaign_id);

-- Insert default ticket types
INSERT INTO ticket_types (name, description, price_cents, color, display_order) VALUES
('Dospělý', 'Vstupenka pro dospělého', 15000, 'primary', 1),
('Dítě do 15 let', 'Vstupenka pro děti do 15 let', 5000, 'success', 2),
('Student', 'Vstupenka pro studenty (platí ISIC)', 8000, 'warning', 3),
('Senior', 'Vstupenka pro seniory nad 65 let', 8000, 'secondary', 4),
('VIP', 'VIP vstupenka s občerstvením', 50000, 'danger', 5);

-- Create view for available tickets with campaign info
CREATE VIEW available_tickets_view AS
SELECT 
    c.id as campaign_id,
    c.title as campaign_title,
    c.description as campaign_description,
    c.external_match_id,
    c.competition_code,
    c.match_date_time,
    c.home_team,
    c.away_team,
    c.venue,
    c.sale_start_time,
    c.sale_end_time,
    tt.id as ticket_type_id,
    tt.name as ticket_type_name,
    tt.description as ticket_type_description,
    COALESCE(ctt.price_cents, tt.price_cents) as price_cents,
    COALESCE(ctt.max_quantity, tt.max_tickets_per_order) as max_per_order,
    tt.color,
    ta.available_quantity,
    ta.total_capacity,
    CASE 
        WHEN NOW() < c.sale_start_time THEN 'upcoming'
        WHEN NOW() > c.sale_end_time THEN 'ended'
        WHEN ta.available_quantity <= 0 THEN 'sold_out'
        ELSE 'available'
    END as sale_status
FROM ticket_campaigns c
JOIN campaign_ticket_types ctt ON c.id = ctt.campaign_id
JOIN ticket_types tt ON ctt.ticket_type_id = tt.id
LEFT JOIN ticket_availability ta ON c.id = ta.campaign_id AND tt.id = ta.ticket_type_id
WHERE c.active = true 
  AND tt.active = true
  AND c.deleted_at IS NULL
  AND tt.deleted_at IS NULL;
