-- ============================================
-- Migration: V20260120_002
-- Description: Migrate billing.subscriptions structure
-- Changes:
--   - Add stripe_subscription_id, stripe_customer_id columns
--   - Add interval column (ENUM: month, year)
--   - Add trial_start, cancel_at, cancel_reason columns
--   - Add price_amount, currency columns
--   - Rename cancelled_at -> canceled_at
--   - Change billing.subscription_status enum value: 'trial' -> 'trialing'
-- ============================================

-- UP Migration
BEGIN;

-- ============================================
-- 1. Ensure billing_interval ENUM exists
-- ============================================

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_type
        WHERE typname = 'billing_interval'
        AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'billing')
    ) THEN
        CREATE TYPE billing.billing_interval AS ENUM ('month', 'year');
        RAISE NOTICE 'Created billing.billing_interval enum';
    END IF;
END $$;

-- ============================================
-- 2. Fix billing.subscription_status enum (trial -> trialing)
-- ============================================

DO $$
DECLARE
    has_trial_value BOOLEAN;
BEGIN
    -- Check if 'trial' exists in the enum (needs migration)
    SELECT EXISTS (
        SELECT 1
        FROM pg_enum e
        JOIN pg_type t ON e.enumtypid = t.oid
        JOIN pg_namespace n ON t.typnamespace = n.oid
        WHERE n.nspname = 'billing'
        AND t.typname = 'subscription_status'
        AND e.enumlabel = 'trial'
    ) INTO has_trial_value;

    IF has_trial_value THEN
        -- PostgreSQL doesn't allow renaming enum values directly
        -- We need to create a new type and migrate

        -- Step 1: Create new enum type
        CREATE TYPE billing.subscription_status_new AS ENUM ('trialing', 'active', 'past_due', 'cancelled', 'expired');

        -- Step 2: Update columns using the old enum
        -- First, change column to use text temporarily
        ALTER TABLE billing.subscriptions
            ALTER COLUMN status TYPE VARCHAR(50) USING status::VARCHAR(50);

        -- Step 3: Update 'trial' to 'trialing'
        UPDATE billing.subscriptions
        SET status = 'trialing'
        WHERE status = 'trial';

        -- Step 4: Drop old type
        DROP TYPE IF EXISTS billing.subscription_status;

        -- Step 5: Rename new type
        ALTER TYPE billing.subscription_status_new RENAME TO subscription_status;

        -- Step 6: Convert column back to enum
        ALTER TABLE billing.subscriptions
            ALTER COLUMN status TYPE billing.subscription_status
            USING status::billing.subscription_status;

        -- Step 7: Restore default
        ALTER TABLE billing.subscriptions
            ALTER COLUMN status SET DEFAULT 'trialing'::billing.subscription_status;

        RAISE NOTICE 'Migrated subscription_status enum: trial -> trialing';
    END IF;
END $$;

-- ============================================
-- 3. Add Stripe columns if they don't exist
-- ============================================

-- stripe_subscription_id
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'stripe_subscription_id'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN stripe_subscription_id VARCHAR(255) UNIQUE;
        CREATE INDEX idx_subscriptions_stripe ON billing.subscriptions(stripe_subscription_id);
        RAISE NOTICE 'Added stripe_subscription_id column';
    END IF;
END $$;

-- stripe_customer_id
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'stripe_customer_id'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN stripe_customer_id VARCHAR(255);
        RAISE NOTICE 'Added stripe_customer_id column';
    END IF;
END $$;

-- ============================================
-- 4. Add interval column
-- ============================================

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'interval'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN "interval" billing.billing_interval DEFAULT 'month';
        RAISE NOTICE 'Added interval column';
    END IF;
END $$;

-- ============================================
-- 5. Add trial and cancellation columns
-- ============================================

-- trial_start
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'trial_start'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN trial_start TIMESTAMPTZ;
        RAISE NOTICE 'Added trial_start column';
    END IF;
END $$;

-- cancel_at (scheduled cancellation date)
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'cancel_at'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN cancel_at TIMESTAMPTZ;
        RAISE NOTICE 'Added cancel_at column';
    END IF;
END $$;

-- cancel_reason
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'cancel_reason'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN cancel_reason VARCHAR(500);
        RAISE NOTICE 'Added cancel_reason column';
    END IF;
END $$;

-- ============================================
-- 6. Add pricing columns
-- ============================================

-- price_amount
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'price_amount'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN price_amount DECIMAL(10, 2);
        RAISE NOTICE 'Added price_amount column';
    END IF;
END $$;

-- currency
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'currency'
    ) THEN
        ALTER TABLE billing.subscriptions ADD COLUMN currency VARCHAR(3) DEFAULT 'USD';
        RAISE NOTICE 'Added currency column';
    END IF;
END $$;

-- ============================================
-- 7. Rename cancelled_at -> canceled_at
-- ============================================

DO $$
BEGIN
    -- Check if cancelled_at exists (British spelling)
    IF EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_schema = 'billing' AND table_name = 'subscriptions' AND column_name = 'cancelled_at'
    ) THEN
        ALTER TABLE billing.subscriptions RENAME COLUMN cancelled_at TO canceled_at;
        RAISE NOTICE 'Renamed cancelled_at to canceled_at';
    END IF;
END $$;

-- ============================================
-- 8. Update comments
-- ============================================

COMMENT ON COLUMN billing.subscriptions.stripe_subscription_id IS 'Stripe subscription ID for payment tracking';
COMMENT ON COLUMN billing.subscriptions.stripe_customer_id IS 'Stripe customer ID';
COMMENT ON COLUMN billing.subscriptions."interval" IS 'Billing interval: month or year';
COMMENT ON COLUMN billing.subscriptions.trial_start IS 'When the trial period started';
COMMENT ON COLUMN billing.subscriptions.cancel_at IS 'Scheduled cancellation date (end of period)';
COMMENT ON COLUMN billing.subscriptions.cancel_reason IS 'Reason for cancellation';
COMMENT ON COLUMN billing.subscriptions.price_amount IS 'Price amount at subscription time';
COMMENT ON COLUMN billing.subscriptions.currency IS 'Currency code (ISO 4217)';

COMMIT;
