-- Clavitor Corporate DB Schema
-- 95% Paddle format + 5% our extensions

-- ============================================
-- PADDLE PRODUCT CATALOG
-- ============================================

CREATE TABLE products (
    id              TEXT PRIMARY KEY,  -- pro_xxx (Paddle ID)
    name            TEXT NOT NULL,     -- "Personal", "Family", "Pro"
    description     TEXT,
    tax_category    TEXT,              -- Paddle tax category
    image_url       TEXT,
    custom_data     TEXT,              -- JSON for our use
    status          TEXT NOT NULL DEFAULT 'active',  -- active, archived
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

CREATE TABLE prices (
    id              TEXT PRIMARY KEY,  -- pri_xxx (Paddle ID)
    product_id      TEXT NOT NULL REFERENCES products(id),
    description     TEXT,              -- Internal notes
    name            TEXT,              -- Shown to customers: "Yearly USD"
    billing_cycle   TEXT,              -- JSON: {"interval": "year", "frequency": 1}
    trial_period    TEXT,              -- JSON or null: {"interval": "day", "frequency": 7}
    tax_mode        TEXT DEFAULT 'account_setting',
    unit_price      TEXT NOT NULL,     -- JSON: {"amount": "1200", "currency_code": "USD"}
    unit_price_overrides TEXT,         -- JSON array for country-specific pricing
    quantity        TEXT,              -- JSON: {"minimum": 1, "maximum": null}
    status          TEXT NOT NULL DEFAULT 'active',
    custom_data     TEXT,              -- JSON: our plan identifier (Personal/Pro/etc)
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

CREATE INDEX idx_prices_product ON prices(product_id);

CREATE TABLE discounts (
    id                          TEXT PRIMARY KEY,  -- dsc_xxx (Paddle ID)
    status                      TEXT NOT NULL DEFAULT 'active',
    description                 TEXT NOT NULL,     -- "Johan MSP - 30% margin"
    enabled_for_checkout        BOOLEAN DEFAULT 0, -- We apply manually, not customer-facing
    code                        TEXT,              -- Null for MSP margins
    type                        TEXT NOT NULL,     -- percentage, flat, flat_per_seat
    mode                        TEXT DEFAULT 'standard',
    amount                      TEXT NOT NULL,     -- "30" for 30%
    currency_code               TEXT,              -- Only for flat types
    recur                       BOOLEAN DEFAULT 1, -- True for subscriptions
    maximum_recurring_intervals INTEGER,
    usage_limit                 INTEGER,
    restrict_to                 TEXT,              -- JSON array of product/price IDs
    expires_at                  INTEGER,
    times_used                  INTEGER DEFAULT 0,
    discount_group_id           TEXT,              -- dsg_xxx for grouping
    custom_data                 TEXT,              -- JSON: {"msp_id": "xxx", "tier": "standard"}
    created_at                  INTEGER NOT NULL,
    updated_at                  INTEGER
);

-- ============================================
-- PADDLE CUSTOMERS + OUR HIERARCHY
-- ============================================

CREATE TABLE customers (
    id                  TEXT PRIMARY KEY,  -- ctm_xxx (Paddle ID)
    
    -- PADDLE FIELDS (95%)
    email               TEXT NOT NULL,
    name                TEXT,
    locale              TEXT DEFAULT 'en',
    status              TEXT NOT NULL DEFAULT 'active',  -- active, archived
    marketing_consent   BOOLEAN DEFAULT 0,
    import_meta         TEXT,              -- JSON if imported
    
    -- OUR EXTENSIONS (5%)
    parent_id           TEXT REFERENCES customers(id),     -- Hierarchy: MSP → Customer → Dept
    level               INTEGER NOT NULL DEFAULT 1,        -- 1=MSP, 2=EndCustomer, 3=Dept
    internal_notes      TEXT,
    
    custom_data         TEXT,              -- JSON: {"source": "web", "segment": "startup"}
    created_at          INTEGER NOT NULL,
    updated_at          INTEGER
);

CREATE INDEX idx_customers_parent ON customers(parent_id);
CREATE INDEX idx_customers_level ON customers(level);

CREATE TABLE addresses (
    id              TEXT PRIMARY KEY,  -- add_xxx (Paddle ID)
    customer_id     TEXT NOT NULL REFERENCES customers(id),
    description     TEXT,
    city            TEXT,
    region          TEXT,
    country_code    TEXT NOT NULL,     -- ISO 3166-1 alpha-2
    zip_code        TEXT,
    status          TEXT NOT NULL DEFAULT 'active',
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

CREATE INDEX idx_addresses_customer ON addresses(customer_id);

CREATE TABLE businesses (
    id              TEXT PRIMARY KEY,  -- biz_xxx (Paddle ID)
    customer_id     TEXT NOT NULL REFERENCES customers(id),
    name            TEXT NOT NULL,     -- Company name
    company_number  TEXT,
    tax_identifier  TEXT,              -- VAT number
    contacts        TEXT,              -- JSON: [{"name": "", "email": ""}]
    status          TEXT NOT NULL DEFAULT 'active',
    custom_data     TEXT,
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

CREATE INDEX idx_businesses_customer ON businesses(customer_id);

-- ============================================
-- PADDLE BILLING + OUR VAULT LINK
-- ============================================

CREATE TABLE subscriptions (
    id                      TEXT PRIMARY KEY,  -- sub_xxx (Paddle ID)
    
    -- PADDLE REFERENCES
    customer_id             TEXT NOT NULL REFERENCES customers(id),
    address_id              TEXT NOT NULL REFERENCES addresses(id),
    business_id             TEXT REFERENCES businesses(id),  -- Optional for B2B
    
    -- PADDLE BILLING
    currency_code           TEXT NOT NULL,
    status                  TEXT NOT NULL,  -- active, past_due, paused, canceled
    collection_mode         TEXT NOT NULL DEFAULT 'automatic',  -- automatic, manual
    billing_details         TEXT,              -- JSON: payment_terms, etc.
    discount                TEXT,              -- JSON: {id, starts_at, ends_at, type}
    
    -- PADDLE TIMESTAMPS
    started_at              INTEGER,
    first_billed_at         INTEGER,
    next_billed_at          INTEGER,
    paused_at               INTEGER,
    canceled_at             INTEGER,
    
    -- OUR EXTENSION (5%): Link to vault
    vault_l0                TEXT,              -- Which vault this subscription pays for
    
    -- PADDLE METADATA
    billing_cycle           TEXT,              -- JSON: {interval, frequency}
    current_billing_period  TEXT,              -- JSON: {starts_at, ends_at}
    scheduled_change        TEXT,              -- JSON: {action, effective_at, resume_at}
    items                   TEXT NOT NULL,     -- JSON array of subscription items
    management_urls         TEXT,              -- JSON: {update_payment_method, cancel}
    custom_data             TEXT,
    import_meta             TEXT,
    created_at              INTEGER NOT NULL,
    updated_at              INTEGER,
    consent_requirements    TEXT               -- JSON array
);

CREATE INDEX idx_subscriptions_customer ON subscriptions(customer_id);
CREATE INDEX idx_subscriptions_vault ON subscriptions(vault_l0);
CREATE INDEX idx_subscriptions_status ON subscriptions(status);

CREATE TABLE subscription_items (
    id                      TEXT PRIMARY KEY,  -- Paddle item ID
    subscription_id         TEXT NOT NULL REFERENCES subscriptions(id),
    price_id                TEXT NOT NULL,     -- pri_xxx
    product_id              TEXT NOT NULL,     -- pro_xxx
    quantity                INTEGER NOT NULL DEFAULT 1,
    status                  TEXT NOT NULL DEFAULT 'active',
    recurring               BOOLEAN DEFAULT 1,
    created_at              INTEGER NOT NULL,
    updated_at              INTEGER,
    previously_billed_at    INTEGER,
    next_billed_at          INTEGER,
    trial_dates             TEXT,              -- JSON: {starts_at, ends_at}
    price_snapshot          TEXT,              -- JSON: price entity at time of add
    product_snapshot        TEXT               -- JSON: product entity at time of add
);

CREATE INDEX idx_items_subscription ON subscription_items(subscription_id);

CREATE TABLE transactions (
    id                  TEXT PRIMARY KEY,  -- txn_xxx (Paddle ID)
    subscription_id     TEXT REFERENCES subscriptions(id),
    customer_id         TEXT NOT NULL REFERENCES customers(id),
    address_id          TEXT NOT NULL REFERENCES addresses(id),
    business_id         TEXT REFERENCES businesses(id),
    invoice_id          TEXT,              -- Deprecated, but Paddle includes it
    invoice_number      TEXT,
    discount_id         TEXT REFERENCES discounts(id),
    
    -- TRANSACTION STATUS
    status              TEXT NOT NULL,  -- ready, billed, completed, past_due, canceled
    origin              TEXT,              -- checkout, api, subscription_renewal, etc.
    
    -- FINANCIALS (from Paddle 'details' object)
    currency_code       TEXT NOT NULL,
    details             TEXT NOT NULL,     -- JSON: totals, tax_rates_used, line_items
    payments            TEXT,              -- JSON array of payment attempts
    
    -- ADJUSTED TOTALS (post-adjustments)
    adjusted_totals     TEXT,
    payout_totals       TEXT,
    adjusted_payout_totals TEXT,
    
    -- INVOICE
    billing_details     TEXT,              -- JSON: enable_checkout, payment_terms, etc.
    additional_information TEXT,           -- Notes on invoice
    purchase_order_number TEXT,
    
    -- CHECKOUT (if applicable)
    checkout_url        TEXT,
    
    -- TIMESTAMPS
    billed_at           INTEGER,
    completed_at        INTEGER,
    revised_at          INTEGER,
    created_at          INTEGER NOT NULL,
    updated_at          INTEGER,
    
    -- OUR EXTENSION: Track if we processed this
    processed_at        INTEGER,
    processing_error    TEXT
);

CREATE INDEX idx_transactions_subscription ON transactions(subscription_id);
CREATE INDEX idx_transactions_customer ON transactions(customer_id);
CREATE INDEX idx_transactions_status ON transactions(status);
CREATE INDEX idx_transactions_billed ON transactions(billed_at);

CREATE TABLE adjustments (
    id                  TEXT PRIMARY KEY,  -- adj_xxx (Paddle ID)
    transaction_id      TEXT NOT NULL REFERENCES transactions(id),
    subscription_id     TEXT REFERENCES subscriptions(id),
    customer_id         TEXT NOT NULL REFERENCES customers(id),
    
    action              TEXT NOT NULL,     -- chargeback, credit, refund
    type                TEXT,              -- partial, full, tax, proration
    amount              TEXT NOT NULL,     -- "1200" cents
    currency_code       TEXT NOT NULL,
    
    totals              TEXT NOT NULL,     -- JSON: adjusted totals
    payout_totals       TEXT,
    
    reason              TEXT,
    credit_applied_to   TEXT,              -- For credit adjustments
    
    created_at          INTEGER NOT NULL
);

-- ============================================
-- OUR VAULT-SPECIFIC DATA (Beyond Paddle)
-- ============================================

CREATE TABLE vaults (
    l0                  TEXT PRIMARY KEY,  -- First 4 bytes of L3, hex
    customer_id         TEXT NOT NULL REFERENCES customers(id),
    subscription_id     TEXT REFERENCES subscriptions(id),
    
    status              TEXT NOT NULL DEFAULT 'active',  -- active, suspended, archived
    created_at          INTEGER NOT NULL,
    last_seen_at        INTEGER,
    
    -- For audit trail
    created_by_human    INTEGER              -- Who created this vault (if tracked)
);

CREATE INDEX idx_vaults_customer ON vaults(customer_id);

-- WL3 Registry (for POP sync) - OUR DATA
CREATE TABLE credentials (
    id                  INTEGER PRIMARY KEY,  -- Our 8-byte int64
    customer_id         TEXT NOT NULL REFERENCES customers(id),
    
    p0                  TEXT NOT NULL,      -- First 4 bytes of PRF (lookup key)
    l0                  TEXT NOT NULL REFERENCES vaults(l0),
    credential_id       BLOB NOT NULL,      -- WebAuthn credential ID
    wl3_path            TEXT NOT NULL,      -- Path in storage: a1/a1b2c3d4/20260405_abc.cla
    
    enrolled_by         INTEGER,            -- Who authorized this device
    created_at          INTEGER NOT NULL,
    last_used_at        INTEGER
);

CREATE INDEX idx_credentials_customer ON credentials(customer_id);
CREATE INDEX idx_credentials_l0 ON credentials(l0);
CREATE INDEX idx_credentials_p0 ON credentials(p0);
CREATE INDEX idx_credentials_created ON credentials(created_at);

-- Our RBAC (not in Paddle - our internal access control)
CREATE TABLE roles (
    id              INTEGER PRIMARY KEY,
    name            TEXT NOT NULL UNIQUE,  -- SuperAdmin, MSPAdmin, TenantAdmin, VaultUser
    permissions     TEXT NOT NULL,          -- JSON
    description     TEXT,
    created_at      INTEGER NOT NULL
);

-- Pre-populate
INSERT INTO roles (id, name, permissions, description, created_at) VALUES
    (1, 'SuperAdmin', '{"all": true}', 'Full system access', strftime('%s', 'now')),
    (2, 'MSPAdmin', '{"customer_admin": true, "billing_view": true}', 'MSP-level admin', strftime('%s', 'now')),
    (3, 'TenantAdmin', '{"vault_create": true, "agent_create": true, "device_enroll": true}', 'Customer admin', strftime('%s', 'now')),
    (4, 'VaultUser', '{"vault_read": true, "vault_write": true}', 'Regular user', strftime('%s', 'now')),
    (5, 'BillingAdmin', '{"billing_view": true, "invoices": true}', 'Can view/pay invoices', strftime('%s', 'now')),
    (6, 'ReadOnly', '{"vault_read": true}', 'View only', strftime('%s', 'now'));

-- Our internal users (humans in our system)
CREATE TABLE humans (
    id              INTEGER PRIMARY KEY,  -- Our 8-byte int64
    customer_id     TEXT REFERENCES customers(id),  -- Can be null for our internal staff
    email           TEXT NOT NULL UNIQUE,
    name            TEXT NOT NULL,
    status          TEXT NOT NULL DEFAULT 'active',
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

-- RBAC: Who has what role for which customer/tenant
CREATE TABLE role_assignments (
    id              INTEGER PRIMARY KEY,
    human_id        INTEGER NOT NULL REFERENCES humans(id),
    customer_id     TEXT NOT NULL REFERENCES customers(id),  -- The tenant they have access to
    role_id         INTEGER NOT NULL REFERENCES roles(id),
    granted_by      INTEGER REFERENCES humans(id),
    created_at      INTEGER NOT NULL,
    UNIQUE(human_id, customer_id, role_id)
);

CREATE INDEX idx_role_assignments_human ON role_assignments(human_id);
CREATE INDEX idx_role_assignments_customer ON role_assignments(customer_id);

-- ============================================
-- POP SYNC STATE (Our distributed system)
-- ============================================

CREATE TABLE pop_sync_state (
    pop_id          TEXT PRIMARY KEY,  -- e.g., "zurich-01", "singapore-02"
    last_sync_at    INTEGER NOT NULL,
    last_sync_cursor INTEGER,  -- Last credential.id synced
    status          TEXT NOT NULL DEFAULT 'active',  -- active, paused, error
    error_message   TEXT,
    updated_at      INTEGER NOT NULL
);

-- ============================================
-- AUDIT LOG (Our record keeping)
-- ============================================

CREATE TABLE events (
    id              INTEGER PRIMARY KEY,
    occurred_at     INTEGER NOT NULL,
    
    -- What happened
    event_type      TEXT NOT NULL,  -- customer_created, subscription_started, payment_received, etc.
    entity_type     TEXT,           -- customer, subscription, transaction, vault, etc.
    entity_id       TEXT,           -- The Paddle or internal ID
    
    -- Who did it / Who it affected
    customer_id     TEXT REFERENCES customers(id),
    human_id        INTEGER REFERENCES humans(id),
    vault_l0        TEXT,
    
    -- Details
    amount_cents    INTEGER,
    currency_code   TEXT,
    details         TEXT,           -- JSON: full event data
    
    -- Source
    source          TEXT DEFAULT 'api',  -- api, webhook, system
    ip_address      TEXT,
    user_agent      TEXT
);

CREATE INDEX idx_events_time ON events(occurred_at);
CREATE INDEX idx_events_customer ON events(customer_id);
CREATE INDEX idx_events_type ON events(event_type);

-- ============================================
-- SYNC TRACKING FIELDS (for dual-write layer)
-- ============================================

-- Track when we last synced with Paddle and what event we processed
-- This helps detect: "We haven't heard from Paddle in X minutes, retry"

ALTER TABLE customers ADD COLUMN last_paddle_sync_at INTEGER;  -- Timestamp of last successful sync
ALTER TABLE customers ADD COLUMN paddle_event_id TEXT;         -- Last webhook event ID processed
ALTER TABLE customers ADD COLUMN pending_since INTEGER;        -- When operation was queued for retry logic

ALTER TABLE subscriptions ADD COLUMN last_paddle_sync_at INTEGER;
ALTER TABLE subscriptions ADD COLUMN paddle_event_id TEXT;
ALTER TABLE subscriptions ADD COLUMN pending_since INTEGER;

ALTER TABLE discounts ADD COLUMN last_paddle_sync_at INTEGER;
ALTER TABLE discounts ADD COLUMN paddle_event_id TEXT;
ALTER TABLE discounts ADD COLUMN pending_since INTEGER;

-- Index for finding stale pending syncs (retry after 5 minutes)
CREATE INDEX idx_subscriptions_pending_sync 
ON subscriptions(sync_status, pending_since) 
WHERE sync_status = 'pending';

CREATE INDEX idx_customers_pending_sync 
ON customers(sync_status, pending_since) 
WHERE sync_status = 'pending';

-- Index for finding records that haven't synced in a while
CREATE INDEX idx_subscriptions_stale_sync 
ON subscriptions(last_paddle_sync_at) 
WHERE last_paddle_sync_at IS NULL OR last_paddle_sync_at < strftime('%s', 'now', '-1 hour');

-- ============================================
-- WL3 STORAGE (for POP distribution)
-- ============================================
-- TODO: Replace with WORM filesystem (256 shards)
-- Path format: {shard}/{p0}/{timestamp}_{random}.cla

CREATE TABLE wl3_storage (
    path            TEXT PRIMARY KEY,
    content         BLOB NOT NULL,  -- The encrypted wrapped L3
    p0              TEXT NOT NULL,    -- For quick lookup
    customer_id     TEXT NOT NULL,
    created_at      INTEGER NOT NULL,
    sync_count      INTEGER DEFAULT 0,  -- How many POPs have pulled this
    last_sync_at    INTEGER
);

CREATE INDEX idx_wl3_p0 ON wl3_storage(p0);
CREATE INDEX idx_wl3_customer ON wl3_storage(customer_id);
CREATE INDEX idx_wl3_created ON wl3_storage(created_at);

-- TODO: SUPER DUPER SECURE POP AUTHENTICATION
-- Requirements:
-- 1. mTLS - POP presents certificate signed by our CA
-- 2. Signed requests - each request signed with POP's private key  
-- 3. Replay protection - nonce + timestamp validation
-- 4. IP allowlist - only known POP IPs
-- 5. Rate limiting per POP ID
-- 6. Request signing with HMAC
-- 7. Audit logging of ALL POP access
-- 8. Short-lived tokens (5 min) with refresh

-- ============================================
-- CURRENCY CONVERSION & PRICING
-- ============================================
-- 
-- DESIGN PRINCIPLE: "Pretty Commercial Prices"
-- -------------------------------------------------
-- We NEVER show exact converted prices (e.g., $29.99 → €27.42).
-- 
-- Why? Because:
--   - €27.42 looks calculated, foreign, and suspicious
--   - €29 looks local, intentional, and trustworthy
--   - Psychological pricing works differently per market
--
-- CONVERSION STRATEGY:
-- 1. Convert USD amount using exchange rate
-- 2. Round UP to "pretty" numbers based on magnitude:
--    - Under €25: Round to nearest €0.99 (€23.21 → €24.00)
--    - €25-€100: Round to nearest €5 (€47.32 → €49.99)
--    - €100-€500: Round to nearest €10 (€123.45 → €129)
--    - €500+: Round to nearest €50 or €99 ending
-- 3. Never drop below margin floor (stored separately)
-- 4. Use currency-local patterns (USD loves .99, JPY loves round 100s)
--
-- This table tracks metadata needed for proper formatting.

CREATE TABLE currencies (
    code            TEXT PRIMARY KEY,   -- ISO 4217: "USD", "EUR", "JPY"
    name            TEXT NOT NULL,      -- "US Dollar", "Euro"
    decimals        INTEGER NOT NULL DEFAULT 2,  -- Minor units: USD=2, JPY=0, BHD=3
    exchange_rate   REAL,               -- vs USD (1 USD = X of this currency). NULL = not fetched yet
    rate_fetched_at INTEGER,            -- When rate was last updated
    symbol          TEXT,               -- "$", "€", "¥"
    symbol_position TEXT DEFAULT 'prefix',  -- 'prefix' ($10) or 'suffix' (10€)
    pretty_pattern  TEXT DEFAULT 'x.99',   -- 'x.99', 'x00', 'x99', 'x50'
    is_active       INTEGER DEFAULT 1,   -- 1 = supported, 0 = disabled
    created_at      INTEGER NOT NULL,
    updated_at      INTEGER
);

-- Exchange rate sources (in priority order):
-- 1. Frankfurter API (free, ECB rates): https://api.frankfurter.app/latest?from=USD
-- 2. Open Exchange Rates (requires API key): https://openexchangerates.org/
-- 3. Paddle's pricing-preview (for customer-facing prices with tax)
-- 
-- NOTE: Exchange rates are fetched dynamically. Seed data below has NULL rates.
-- Run: go run scripts/update_rates.go to populate exchange_rate column.

-- Comprehensive ISO 4217 currency list (top 50 by trading volume)
-- Rates should be fetched from Frankfurter API (free, no API key required)
INSERT INTO currencies (code, name, decimals, exchange_rate, symbol, symbol_position, pretty_pattern, is_active, created_at) VALUES
-- Major reserve currencies (always active)
('USD', 'US Dollar', 2, NULL, '$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('EUR', 'Euro', 2, NULL, '€', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('GBP', 'British Pound', 2, NULL, '£', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('JPY', 'Japanese Yen', 0, NULL, '¥', 'prefix', 'x00', 1, strftime('%s', 'now')),
('CNY', 'Chinese Yuan', 2, NULL, '¥', 'prefix', 'x.00', 1, strftime('%s', 'now')),

-- Other major trading currencies
('AUD', 'Australian Dollar', 2, NULL, 'A$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('CAD', 'Canadian Dollar', 2, NULL, 'C$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('CHF', 'Swiss Franc', 2, NULL, 'Fr', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('SEK', 'Swedish Krona', 2, NULL, 'kr', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('NZD', 'New Zealand Dollar', 2, NULL, 'NZ$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('SGD', 'Singapore Dollar', 2, NULL, 'S$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('HKD', 'Hong Kong Dollar', 2, NULL, 'HK$', 'prefix', 'x.99', 1, strftime('%s', 'now')),
('NOK', 'Norwegian Krone', 2, NULL, 'kr', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('MXN', 'Mexican Peso', 2, NULL, '$', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('INR', 'Indian Rupee', 2, NULL, '₹', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('BRL', 'Brazilian Real', 2, NULL, 'R$', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('ZAR', 'South African Rand', 2, NULL, 'R', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('KRW', 'South Korean Won', 0, NULL, '₩', 'prefix', 'x000', 1, strftime('%s', 'now')),
('TWD', 'New Taiwan Dollar', 2, NULL, 'NT$', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('DKK', 'Danish Krone', 2, NULL, 'kr', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('PLN', 'Polish Zloty', 2, NULL, 'zł', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('THB', 'Thai Baht', 2, NULL, '฿', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('IDR', 'Indonesian Rupiah', 2, NULL, 'Rp', 'prefix', 'x000', 1, strftime('%s', 'now')),
('HUF', 'Hungarian Forint', 2, NULL, 'Ft', 'suffix', 'x00', 1, strftime('%s', 'now')),
('CZK', 'Czech Koruna', 2, NULL, 'Kč', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('ILS', 'Israeli Shekel', 2, NULL, '₪', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('CLP', 'Chilean Peso', 0, NULL, '$', 'prefix', 'x00', 1, strftime('%s', 'now')),
('PHP', 'Philippine Peso', 2, NULL, '₱', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('AED', 'UAE Dirham', 2, NULL, 'Dh', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('COP', 'Colombian Peso', 2, NULL, '$', 'prefix', 'x00', 1, strftime('%s', 'now')),
('SAR', 'Saudi Riyal', 2, NULL, '﷼', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('MYR', 'Malaysian Ringgit', 2, NULL, 'RM', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('RON', 'Romanian Leu', 2, NULL, 'lei', 'suffix', 'x.00', 1, strftime('%s', 'now')),

-- Middle Eastern (3-decimal currencies)
('BHD', 'Bahraini Dinar', 3, NULL, 'BD', 'prefix', 'x.000', 0, strftime('%s', 'now')),
('KWD', 'Kuwaiti Dinar', 3, NULL, 'KD', 'prefix', 'x.000', 0, strftime('%s', 'now')),
('OMR', 'Omani Rial', 3, NULL, 'OR', 'prefix', 'x.000', 0, strftime('%s', 'now')),
('JOD', 'Jordanian Dinar', 3, NULL, 'JD', 'prefix', 'x.000', 0, strftime('%s', 'now')),

-- Other European
('TRY', 'Turkish Lira', 2, NULL, '₺', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('RUB', 'Russian Ruble', 2, NULL, '₽', 'suffix', 'x.00', 0, strftime('%s', 'now')),  -- Sanctions
('UAH', 'Ukrainian Hryvnia', 2, NULL, '₴', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('BGN', 'Bulgarian Lev', 2, NULL, 'лв', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('HRK', 'Croatian Kuna', 2, NULL, 'kn', 'suffix', 'x.00', 1, strftime('%s', 'now')),
('ISK', 'Icelandic Krona', 0, NULL, 'kr', 'suffix', 'x00', 1, strftime('%s', 'now')),

-- African
('EGP', 'Egyptian Pound', 2, NULL, '£', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('NGN', 'Nigerian Naira', 2, NULL, '₦', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('KES', 'Kenyan Shilling', 2, NULL, 'KSh', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('GHS', 'Ghanaian Cedi', 2, NULL, '₵', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('MAD', 'Moroccan Dirham', 2, NULL, 'DH', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('TND', 'Tunisian Dinar', 3, NULL, 'DT', 'prefix', 'x.000', 0, strftime('%s', 'now')),

-- Asian
('PKR', 'Pakistani Rupee', 2, NULL, '₨', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('BDT', 'Bangladeshi Taka', 2, NULL, '৳', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('VND', 'Vietnamese Dong', 0, NULL, '₫', 'suffix', 'x000', 1, strftime('%s', 'now')),
('MMK', 'Myanmar Kyat', 2, NULL, 'K', 'suffix', 'x00', 0, strftime('%s', 'now')),
('KHR', 'Cambodian Riel', 2, NULL, '៛', 'prefix', 'x00', 0, strftime('%s', 'now')),
('LAK', 'Lao Kip', 2, NULL, '₭', 'prefix', 'x000', 0, strftime('%s', 'now')),
('MNT', 'Mongolian Tugrik', 2, NULL, '₮', 'suffix', 'x00', 0, strftime('%s', 'now')),

-- Latin American
('ARS', 'Argentine Peso', 2, NULL, '$', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('PEN', 'Peruvian Sol', 2, NULL, 'S/', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('UYU', 'Uruguayan Peso', 2, NULL, '$', 'prefix', 'x.00', 1, strftime('%s', 'now')),
('PYG', 'Paraguayan Guarani', 0, NULL, '₲', 'prefix', 'x000', 0, strftime('%s', 'now')),
('BOB', 'Bolivian Boliviano', 2, NULL, 'Bs', 'prefix', 'x.00', 0, strftime('%s', 'now')),

-- Caribbean
('XCD', 'Eastern Caribbean Dollar', 2, NULL, '$', 'prefix', 'x.99', 0, strftime('%s', 'now'));  -- Eastern Caribbean


