-- Backs crates/invoice (InvoiceService, BillingProfileRepo) — GST-compliant
-- invoice generation for Tracecoin/package purchases. Never created by any
-- active migration (same root cause as everything else fixed this session):
-- init-db.sql has a much simpler, older `invoices` shape that doesn't match
-- what InvoiceService actually reads/writes (no GST breakdown, seller/
-- customer snapshot, or line items), so it wasn't used as the reference here
-- — the schema below matches crates/invoice/src/lib.rs's Invoice/LineItem
-- structs and crates/invoice/src/service.rs's queries exactly.
CREATE TABLE IF NOT EXISTS invoices (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    invoice_number VARCHAR(50) NOT NULL UNIQUE,
    payment_id UUID NOT NULL REFERENCES payments(id),
    user_id UUID NOT NULL REFERENCES users(id),
    status VARCHAR(20) NOT NULL DEFAULT 'ISSUED',
    currency VARCHAR(10) NOT NULL DEFAULT 'INR',
    invoice_type VARCHAR(50) NOT NULL DEFAULT 'TRACECOIN_PURCHASE',
    subtotal INTEGER NOT NULL,
    discount_amount INTEGER NOT NULL DEFAULT 0,
    cgst_rate DOUBLE PRECISION NOT NULL DEFAULT 0,
    cgst_amount INTEGER NOT NULL DEFAULT 0,
    sgst_rate DOUBLE PRECISION NOT NULL DEFAULT 0,
    sgst_amount INTEGER NOT NULL DEFAULT 0,
    igst_rate DOUBLE PRECISION NOT NULL DEFAULT 0,
    igst_amount INTEGER NOT NULL DEFAULT 0,
    total INTEGER NOT NULL,
    reverse_charge BOOLEAN NOT NULL DEFAULT false,
    seller_name VARCHAR(255) NOT NULL,
    seller_address TEXT NOT NULL,
    seller_gstin VARCHAR(20),
    seller_pan VARCHAR(20),
    seller_state_code VARCHAR(10),
    place_of_supply_state VARCHAR(10),
    customer_name VARCHAR(255),
    customer_email VARCHAR(255),
    customer_phone VARCHAR(20),
    customer_billing_address TEXT,
    customer_gstin VARCHAR(20),
    customer_state_code VARCHAR(10),
    discount_label VARCHAR(255),
    notes TEXT,
    pdf_object_key VARCHAR(500),
    issued_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    paid_at TIMESTAMPTZ,
    voided_at TIMESTAMPTZ,
    voided_by_user_id UUID REFERENCES users(id),
    void_reason TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_invoices_user_id ON invoices(user_id);
CREATE INDEX IF NOT EXISTS idx_invoices_payment_id ON invoices(payment_id);
CREATE INDEX IF NOT EXISTS idx_invoices_status ON invoices(status);

CREATE TABLE IF NOT EXISTS invoice_line_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    invoice_id UUID NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
    line_number INTEGER NOT NULL,
    description VARCHAR(500) NOT NULL,
    hsn_sac_code VARCHAR(20),
    quantity DOUBLE PRECISION NOT NULL DEFAULT 1,
    unit_price_inr INTEGER NOT NULL,
    line_subtotal_inr INTEGER NOT NULL,
    tax_rate DOUBLE PRECISION NOT NULL DEFAULT 0,
    line_tax_inr INTEGER NOT NULL DEFAULT 0,
    line_total_inr INTEGER NOT NULL,
    metadata JSONB
);
CREATE INDEX IF NOT EXISTS idx_invoice_line_items_invoice_id ON invoice_line_items(invoice_id);

-- Default billing details a user has on file, used to prefill invoices
-- without asking again on every purchase (BillingProfileRepo).
CREATE TABLE IF NOT EXISTS billing_profiles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    legal_name VARCHAR(255) NOT NULL,
    email VARCHAR(255),
    phone VARCHAR(20),
    gstin VARCHAR(20),
    pan VARCHAR(20),
    billing_address TEXT NOT NULL,
    state_code VARCHAR(10),
    is_default BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_billing_profiles_user_id ON billing_profiles(user_id);

-- InvoiceService::create allocates invoice numbers from this sequence
-- (crates/invoice/src/service.rs: `SELECT nextval('invoice_number_seq')`).
CREATE SEQUENCE IF NOT EXISTS invoice_number_seq;
