-- ============================================================
-- QZ TOKEN SYSTEM — quiXzoom Token & Payment Schema
-- ============================================================
-- Komplett schema inklusive zoomers, missions, observations

-- ============================================================
-- ZOOMERS
-- ============================================================

CREATE TABLE zoomers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE,
    phone VARCHAR(50),
    status VARCHAR(50) DEFAULT 'active',
    capabilities JSONB DEFAULT '[]',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ============================================================
-- AREAS
-- ============================================================

CREATE TABLE areas (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    country VARCHAR(100),
    city VARCHAR(100),
    priority FLOAT DEFAULT 0.5,
    status VARCHAR(50) DEFAULT 'active',
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ============================================================
-- OBSERVATIONS
-- ============================================================

CREATE TABLE observations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    observation_id VARCHAR(255) UNIQUE NOT NULL,
    source_type VARCHAR(50) NOT NULL,
    source_id VARCHAR(255),
    zoomer_id UUID REFERENCES zoomers(id),
    media_type VARCHAR(50),
    media_url TEXT,
    status VARCHAR(50) DEFAULT 'pending',
    validated_by VARCHAR(255),
    validated_at TIMESTAMP WITH TIME ZONE,
    ai_analysis JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ============================================================
-- OBJECTS
-- ============================================================

CREATE TABLE objects (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    object_id VARCHAR(255) UNIQUE NOT NULL,
    type VARCHAR(100) NOT NULL,
    subtype VARCHAR(100),
    status VARCHAR(50) DEFAULT 'active',
    verification_status VARCHAR(50) DEFAULT 'unverified',
    confidence FLOAT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ============================================================
-- MISSIONS
-- ============================================================

CREATE TABLE missions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    mission_id VARCHAR(255) UNIQUE NOT NULL,
    type VARCHAR(50) NOT NULL,
    area_id UUID REFERENCES areas(id),
    assigned_to UUID REFERENCES zoomers(id),
    assigned_at TIMESTAMP WITH TIME ZONE,
    status VARCHAR(50) DEFAULT 'pending',
    result JSONB DEFAULT '{}',
    completed_at TIMESTAMP WITH TIME ZONE,
    priority FLOAT DEFAULT 0.5,
    instructions JSONB DEFAULT '[]',
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ============================================================
-- ZOOMER WALLETS
-- ============================================================

CREATE TABLE zoomer_wallets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    zoomer_id UUID NOT NULL REFERENCES zoomers(id) ON DELETE CASCADE,
    balance_qz_token DECIMAL(18, 8) DEFAULT 0.0,
    balance_pending_qz_token DECIMAL(18, 8) DEFAULT 0.0,
    stripe_connect_account_id VARCHAR(255),
    stripe_connect_status VARCHAR(50) DEFAULT 'pending',
    payout_schedule VARCHAR(50) DEFAULT 'weekly_monday',
    payout_minimum_qz_token DECIMAL(18, 8) DEFAULT 10.0,
    status VARCHAR(50) DEFAULT 'active',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(zoomer_id)
);

CREATE INDEX idx_zoomer_wallets_zoomer ON zoomer_wallets(zoomer_id);
CREATE INDEX idx_zoomer_wallets_stripe ON zoomer_wallets(stripe_connect_account_id);

-- ============================================================
-- TOKEN TRANSACTIONS (Immutable Ledger)
-- ============================================================

CREATE TABLE token_transactions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tx_hash VARCHAR(255) UNIQUE NOT NULL,
    tx_type VARCHAR(50) NOT NULL,
    from_wallet_id UUID REFERENCES zoomer_wallets(id),
    to_wallet_id UUID REFERENCES zoomer_wallets(id),
    amount_qz_token DECIMAL(18, 8) NOT NULL,
    amount_usd DECIMAL(18, 8) NOT NULL,
    exchange_rate DECIMAL(18, 8) NOT NULL,
    mission_id UUID REFERENCES missions(id),
    observation_id UUID REFERENCES observations(id),
    stripe_payment_intent_id VARCHAR(255),
    stripe_payout_id VARCHAR(255),
    description TEXT,
    metadata JSONB DEFAULT '{}',
    signature VARCHAR(512),
    signed_by VARCHAR(255),
    status VARCHAR(50) DEFAULT 'confirmed',
    confirmed_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    CONSTRAINT no_negative_amount CHECK (amount_qz_token >= 0)
);

CREATE INDEX idx_token_tx_hash ON token_transactions(tx_hash);
CREATE INDEX idx_token_tx_from ON token_transactions(from_wallet_id);
CREATE INDEX idx_token_tx_to ON token_transactions(to_wallet_id);
CREATE INDEX idx_token_tx_type ON token_transactions(tx_type);
CREATE INDEX idx_token_tx_mission ON token_transactions(mission_id);
CREATE INDEX idx_token_tx_created ON token_transactions(created_at);

-- ============================================================
-- MISSION PRICING
-- ============================================================

CREATE TABLE mission_pricing (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    mission_type VARCHAR(50) NOT NULL,
    base_price_qz_token DECIMAL(18, 8) NOT NULL,
    base_price_usd DECIMAL(18, 8) NOT NULL,
    complexity_multiplier DECIMAL(5, 2) DEFAULT 1.0,
    distance_bonus_qz_token DECIMAL(18, 8) DEFAULT 0.0,
    time_bonus_qz_token DECIMAL(18, 8) DEFAULT 0.0,
    quality_bonus_qz_token DECIMAL(18, 8) DEFAULT 0.0,
    min_price_qz_token DECIMAL(18, 8) DEFAULT 0.5,
    max_price_qz_token DECIMAL(18, 8) DEFAULT 100.0,
    country_code VARCHAR(10),
    city VARCHAR(100),
    status VARCHAR(50) DEFAULT 'active',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(mission_type, country_code, city)
);

CREATE INDEX idx_mission_pricing_type ON mission_pricing(mission_type);
CREATE INDEX idx_mission_pricing_geo ON mission_pricing(country_code, city);

-- ============================================================
-- PAYOUT SCHEDULES
-- ============================================================

CREATE TABLE payout_schedules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    zoomer_id UUID NOT NULL REFERENCES zoomers(id),
    wallet_id UUID NOT NULL REFERENCES zoomer_wallets(id),
    day_of_week INTEGER NOT NULL DEFAULT 1,
    time_of_day TIME NOT NULL DEFAULT '09:00:00',
    timezone VARCHAR(50) DEFAULT 'UTC',
    minimum_qz_token DECIMAL(18, 8) DEFAULT 10.0,
    status VARCHAR(50) DEFAULT 'active',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(zoomer_id)
);

CREATE INDEX idx_payout_schedules_zoomer ON payout_schedules(zoomer_id);
CREATE INDEX idx_payout_schedules_day ON payout_schedules(day_of_week);

-- ============================================================
-- PAYOUT EXECUTIONS
-- ============================================================

CREATE TABLE payout_executions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    zoomer_id UUID NOT NULL REFERENCES zoomers(id),
    wallet_id UUID NOT NULL REFERENCES zoomer_wallets(id),
    amount_qz_token DECIMAL(18, 8) NOT NULL,
    amount_usd DECIMAL(18, 8) NOT NULL,
    exchange_rate DECIMAL(18, 8) NOT NULL,
    stripe_payout_id VARCHAR(255),
    stripe_transfer_id VARCHAR(255),
    status VARCHAR(50) DEFAULT 'pending',
    error_message TEXT,
    retry_count INTEGER DEFAULT 0,
    processed_at TIMESTAMP WITH TIME ZONE,
    completed_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    CONSTRAINT no_negative_payout CHECK (amount_qz_token > 0)
);

CREATE INDEX idx_payout_exec_zoomer ON payout_executions(zoomer_id);
CREATE INDEX idx_payout_exec_status ON payout_executions(status);
CREATE INDEX idx_payout_exec_stripe ON payout_executions(stripe_payout_id);

-- ============================================================
-- CUSTOMER TOP-UPS
-- ============================================================

CREATE TABLE customer_topups (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    customer_id VARCHAR(255) NOT NULL,
    amount_qz_token DECIMAL(18, 8) NOT NULL,
    amount_usd DECIMAL(18, 8) NOT NULL,
    exchange_rate DECIMAL(18, 8) NOT NULL,
    stripe_payment_intent_id VARCHAR(255),
    stripe_charge_id VARCHAR(255),
    status VARCHAR(50) DEFAULT 'pending',
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    completed_at TIMESTAMP WITH TIME ZONE
);

CREATE INDEX idx_customer_topups_customer ON customer_topups(customer_id);
CREATE INDEX idx_customer_topups_stripe ON customer_topups(stripe_payment_intent_id);

-- ============================================================
-- VIEWS
-- ============================================================

CREATE VIEW zoomer_balance AS
SELECT 
    z.id as zoomer_id,
    z.name as zoomer_name,
    zw.id as wallet_id,
    zw.balance_qz_token,
    zw.balance_pending_qz_token,
    zw.balance_qz_token + zw.balance_pending_qz_token as total_balance,
    zw.stripe_connect_status,
    zw.payout_schedule
FROM zoomers z
JOIN zoomer_wallets zw ON zw.zoomer_id = z.id;

CREATE VIEW token_flow_summary AS
SELECT 
    DATE_TRUNC('day', created_at) as date,
    tx_type,
    COUNT(*) as transaction_count,
    SUM(amount_qz_token) as total_qz_token,
    SUM(amount_usd) as total_usd
FROM token_transactions
WHERE status = 'confirmed'
GROUP BY DATE_TRUNC('day', created_at), tx_type
ORDER BY date DESC, tx_type;

-- ============================================================
-- TRIGGERS
-- ============================================================

CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_zoomers_updated_at BEFORE UPDATE ON zoomers
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_areas_updated_at BEFORE UPDATE ON areas
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_objects_updated_at BEFORE UPDATE ON objects
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_missions_updated_at BEFORE UPDATE ON missions
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_zoomer_wallets_updated_at BEFORE UPDATE ON zoomer_wallets
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_mission_pricing_updated_at BEFORE UPDATE ON mission_pricing
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_payout_schedules_updated_at BEFORE UPDATE ON payout_schedules
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- ============================================================
-- LEDGER INTEGRITY
-- ============================================================

CREATE OR REPLACE FUNCTION prevent_tx_update()
RETURNS TRIGGER AS $$
BEGIN
    IF OLD.status = 'confirmed' THEN
        RAISE EXCEPTION 'Cannot modify confirmed transaction: %', OLD.tx_hash;
    END IF;
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER prevent_confirmed_tx_update BEFORE UPDATE ON token_transactions
    FOR EACH ROW EXECUTE FUNCTION prevent_tx_update();

CREATE OR REPLACE FUNCTION prevent_tx_delete()
RETURNS TRIGGER AS $$
BEGIN
    RAISE EXCEPTION 'Cannot delete transactions from immutable ledger';
END;
$$ language 'plpgsql';

CREATE TRIGGER prevent_tx_deletion BEFORE DELETE ON token_transactions
    FOR EACH ROW EXECUTE FUNCTION prevent_tx_delete();
