-- IT0 Billing Tables (public schema)
-- Phase 2: Subscription management + invoicing

-- Invoice number sequence
CREATE SEQUENCE IF NOT EXISTS billing_invoice_number_seq START 1000;

-- Plans
CREATE TABLE IF NOT EXISTS billing_plans (
    id                          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name                        VARCHAR(50) NOT NULL UNIQUE,   -- free, pro, enterprise
    display_name                VARCHAR(100) NOT NULL,
    monthly_price_usd_cents     INTEGER NOT NULL DEFAULT 0,
    monthly_price_cny           INTEGER NOT NULL DEFAULT 0,    -- in fen (1/100 yuan)
    included_tokens_per_month   BIGINT NOT NULL DEFAULT 100000,
    overage_rate_cents_per_m_token INTEGER NOT NULL DEFAULT 0, -- per million tokens
    max_servers                 INTEGER NOT NULL DEFAULT 5,    -- -1 = unlimited
    max_users                   INTEGER NOT NULL DEFAULT 3,
    max_standing_orders         INTEGER NOT NULL DEFAULT 10,
    hard_limit_percent          INTEGER NOT NULL DEFAULT 100,  -- 0 = no hard limit
    trial_days                  INTEGER NOT NULL DEFAULT 0,
    is_active                   BOOLEAN NOT NULL DEFAULT TRUE,
    created_at                  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at                  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Subscriptions
CREATE TABLE IF NOT EXISTS billing_subscriptions (
    id                    UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id             UUID NOT NULL REFERENCES public.tenants(id),
    plan_id               UUID NOT NULL REFERENCES billing_plans(id),
    status                VARCHAR(20) NOT NULL DEFAULT 'trialing',
    current_period_start  TIMESTAMPTZ NOT NULL,
    current_period_end    TIMESTAMPTZ NOT NULL,
    trial_ends_at         TIMESTAMPTZ,
    cancel_at_period_end  BOOLEAN NOT NULL DEFAULT FALSE,
    cancelled_at          TIMESTAMPTZ,
    next_plan_id          UUID REFERENCES billing_plans(id),
    created_at            TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at            TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_billing_subs_tenant ON billing_subscriptions(tenant_id);
CREATE INDEX IF NOT EXISTS idx_billing_subs_status ON billing_subscriptions(status);
CREATE INDEX IF NOT EXISTS idx_billing_subs_period_end ON billing_subscriptions(current_period_end);

-- Invoices
CREATE TABLE IF NOT EXISTS billing_invoices (
    id               UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id        UUID NOT NULL REFERENCES public.tenants(id),
    subscription_id  UUID REFERENCES billing_subscriptions(id),
    invoice_number   VARCHAR(50) NOT NULL UNIQUE,
    status           VARCHAR(20) NOT NULL DEFAULT 'open',  -- open, paid, void, past_due, uncollectible
    currency         VARCHAR(3) NOT NULL DEFAULT 'USD',
    subtotal_cents   INTEGER NOT NULL DEFAULT 0,
    tax_cents        INTEGER NOT NULL DEFAULT 0,
    total_cents      INTEGER NOT NULL DEFAULT 0,
    amount_due_cents INTEGER NOT NULL DEFAULT 0,
    period_start     TIMESTAMPTZ NOT NULL,
    period_end       TIMESTAMPTZ NOT NULL,
    due_date         TIMESTAMPTZ NOT NULL,
    paid_at          TIMESTAMPTZ,
    created_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at       TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_billing_invoices_tenant ON billing_invoices(tenant_id);
CREATE INDEX IF NOT EXISTS idx_billing_invoices_status ON billing_invoices(status);

-- Invoice Items
CREATE TABLE IF NOT EXISTS billing_invoice_items (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    invoice_id  UUID NOT NULL REFERENCES billing_invoices(id) ON DELETE CASCADE,
    item_type   VARCHAR(30) NOT NULL,  -- subscription, overage, credit, adjustment
    description TEXT NOT NULL,
    quantity    BIGINT NOT NULL DEFAULT 1,
    unit_price  INTEGER NOT NULL,      -- cents
    amount      INTEGER NOT NULL,      -- cents
    currency    VARCHAR(3) NOT NULL DEFAULT 'USD',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_billing_items_invoice ON billing_invoice_items(invoice_id);

-- Payments
CREATE TABLE IF NOT EXISTS billing_payments (
    id                   UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id            UUID NOT NULL REFERENCES public.tenants(id),
    invoice_id           UUID NOT NULL REFERENCES billing_invoices(id),
    provider             VARCHAR(20) NOT NULL,  -- stripe, alipay, wechat_pay, crypto
    provider_payment_id  VARCHAR(255) NOT NULL UNIQUE,
    amount_cents         INTEGER NOT NULL,
    currency             VARCHAR(3) NOT NULL,
    status               VARCHAR(20) NOT NULL DEFAULT 'pending',  -- pending, succeeded, failed, refunded
    paid_at              TIMESTAMPTZ,
    metadata             JSONB,
    created_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_billing_payments_tenant ON billing_payments(tenant_id);
CREATE INDEX IF NOT EXISTS idx_billing_payments_provider_id ON billing_payments(provider_payment_id);

-- Payment Methods
CREATE TABLE IF NOT EXISTS billing_payment_methods (
    id                   UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id            UUID NOT NULL REFERENCES public.tenants(id),
    provider             VARCHAR(20) NOT NULL,
    display_name         VARCHAR(200) NOT NULL,
    provider_customer_id VARCHAR(255),
    details              JSONB,  -- masked card info, alipay account, etc. NO raw card numbers
    is_default           BOOLEAN NOT NULL DEFAULT FALSE,
    expires_at           TIMESTAMPTZ,
    created_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_billing_methods_tenant ON billing_payment_methods(tenant_id);

-- Monthly Usage Aggregates
CREATE TABLE IF NOT EXISTS billing_usage_aggregates (
    id                   UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id            UUID NOT NULL REFERENCES public.tenants(id),
    year                 INTEGER NOT NULL,
    month                INTEGER NOT NULL,  -- 1-12
    period_start         TIMESTAMPTZ NOT NULL,
    period_end           TIMESTAMPTZ NOT NULL,
    total_input_tokens   BIGINT NOT NULL DEFAULT 0,
    total_output_tokens  BIGINT NOT NULL DEFAULT 0,
    total_tokens         BIGINT NOT NULL DEFAULT 0,
    total_cost_usd       NUMERIC(12, 6) NOT NULL DEFAULT 0,
    task_count           INTEGER NOT NULL DEFAULT 0,
    created_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(tenant_id, year, month)
);

CREATE INDEX IF NOT EXISTS idx_billing_usage_tenant_period ON billing_usage_aggregates(tenant_id, year, month);

-- Add max_standing_orders column to tenants if missing
ALTER TABLE public.tenants ADD COLUMN IF NOT EXISTS max_standing_orders INTEGER NOT NULL DEFAULT 10;
ALTER TABLE public.tenants ADD COLUMN IF NOT EXISTS max_agent_tokens_per_month BIGINT NOT NULL DEFAULT 100000;
