-- 007_refunds.sql
-- Refund tracking for failed filings that were not the customer's fault.
-- Covers: state portal errors, payment processing failures, name collisions
-- discovered after payment, state rejections, etc.

BEGIN;

CREATE TABLE IF NOT EXISTS refunds (
    id                  SERIAL PRIMARY KEY,
    refund_number       TEXT UNIQUE NOT NULL,       -- REF-2026-XXXXXX
    -- What's being refunded
    order_type          TEXT NOT NULL CHECK (order_type IN ('formation', 'service')),
    order_id            INTEGER,                    -- FK to formation_orders.id or orders.id
    order_number        TEXT NOT NULL,              -- PW-2026-XXXX or ORD-2026-XXXX
    -- Who
    customer_name       TEXT NOT NULL,
    customer_email      TEXT NOT NULL,
    -- Amount
    original_amount_cents   INTEGER NOT NULL,       -- what was originally charged
    refund_amount_cents     INTEGER NOT NULL,       -- what we're refunding (may be partial)
    refund_type         TEXT NOT NULL CHECK (refund_type IN ('full', 'partial', 'state_fee_only', 'service_fee_only')),
    -- Why
    reason_category     TEXT NOT NULL CHECK (reason_category IN (
        'state_portal_error',       -- state portal down, rejected filing incorrectly
        'payment_failed',           -- card charged but filing didn't go through
        'name_collision',           -- name became unavailable between search and filing
        'state_rejected',           -- state rejected the filing after payment
        'automation_error',         -- our automation failed and couldn't recover
        'duplicate_charge',         -- accidentally charged twice
        'customer_request',         -- customer changed mind (discretionary)
        'other'
    )),
    reason_detail       TEXT,                       -- free-text explanation
    -- State fee recovery
    state_fee_recoverable   BOOLEAN DEFAULT FALSE,  -- can we get the state fee back?
    state_fee_recovered     BOOLEAN DEFAULT FALSE,
    state_fee_recovery_notes TEXT,
    -- Processing
    status              TEXT DEFAULT 'pending' CHECK (status IN (
        'pending',          -- refund requested, not yet approved
        'approved',         -- admin approved, ready to process
        'processing',       -- refund being sent via Relay
        'sent',             -- ACH/card refund sent
        'confirmed',        -- customer confirmed receipt
        'denied',           -- refund request denied (with reason)
        'cancelled'
    )),
    -- Approval
    requested_by        TEXT,                       -- 'system', 'admin', 'customer'
    requested_at        TIMESTAMPTZ DEFAULT now(),
    approved_by         INTEGER,                    -- admin_users.id
    approved_at         TIMESTAMPTZ,
    denied_reason       TEXT,
    -- Payment
    refund_method       TEXT CHECK (refund_method IN ('relay_ach', 'card_reversal', 'check', 'credit')),
    relay_transaction_id TEXT,
    sent_at             TIMESTAMPTZ,
    confirmed_at        TIMESTAMPTZ,
    -- Metadata
    admin_notes         TEXT,
    created_at          TIMESTAMPTZ DEFAULT now(),
    updated_at          TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_refunds_order ON refunds(order_type, order_id);
CREATE INDEX IF NOT EXISTS idx_refunds_status ON refunds(status);
CREATE INDEX IF NOT EXISTS idx_refunds_number ON refunds(refund_number);
CREATE INDEX IF NOT EXISTS idx_refunds_email ON refunds(customer_email);

-- Add refund tracking to formation_orders
ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS refund_id INTEGER REFERENCES refunds(id);
ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS refunded BOOLEAN DEFAULT FALSE;

-- Add refund tracking to general orders
ALTER TABLE orders ADD COLUMN IF NOT EXISTS refund_id INTEGER REFERENCES refunds(id);
ALTER TABLE orders ADD COLUMN IF NOT EXISTS refunded BOOLEAN DEFAULT FALSE;

COMMIT;
