-- ============================================
-- TEMPLATE-SAAS: Commissions Tables
-- Version: 1.0.0
-- Module: SAAS-020
-- ============================================

-- ============================================
-- Commission Schemes (configuration templates)
-- ============================================
CREATE TABLE commissions.schemes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Basic info
    name VARCHAR(100) NOT NULL,
    description TEXT,

    -- Commission type and rates
    type commissions.scheme_type NOT NULL DEFAULT 'percentage',
    rate DECIMAL(5, 2) DEFAULT 0,              -- For percentage type (0-100%)
    fixed_amount DECIMAL(15, 2) DEFAULT 0,     -- For fixed type
    tiers JSONB DEFAULT '[]'::jsonb,           -- For tiered type: [{from: 0, to: 1000, rate: 5}, ...]

    -- Application scope
    applies_to commissions.applies_to DEFAULT 'all',
    product_ids UUID[] DEFAULT '{}',           -- When applies_to = 'products'
    category_ids UUID[] DEFAULT '{}',          -- When applies_to = 'categories'

    -- Amount constraints
    min_amount DECIMAL(15, 2) DEFAULT 0,       -- Minimum sale amount to qualify
    max_amount DECIMAL(15, 2),                 -- Maximum commission per sale (cap)

    -- Status
    is_active BOOLEAN DEFAULT TRUE,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    created_by UUID REFERENCES users.users(id) ON DELETE SET NULL,
    deleted_at TIMESTAMPTZ,

    -- Constraints
    CONSTRAINT check_rate_range CHECK (rate >= 0 AND rate <= 100),
    CONSTRAINT check_fixed_positive CHECK (fixed_amount >= 0),
    CONSTRAINT check_min_max CHECK (min_amount >= 0 AND (max_amount IS NULL OR max_amount >= min_amount))
);

COMMENT ON TABLE commissions.schemes IS 'Commission scheme configurations';
COMMENT ON COLUMN commissions.schemes.rate IS 'Commission rate as percentage (0-100)';
COMMENT ON COLUMN commissions.schemes.tiers IS 'JSON array of tier configurations: [{from, to, rate}]';

-- ============================================
-- Commission Assignments (user-scheme mapping)
-- ============================================
CREATE TABLE commissions.assignments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Assignment mapping
    user_id UUID NOT NULL REFERENCES users.users(id) ON DELETE CASCADE,
    scheme_id UUID NOT NULL REFERENCES commissions.schemes(id) ON DELETE CASCADE,

    -- Validity period
    starts_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    ends_at TIMESTAMPTZ,                       -- NULL = no end date

    -- Override
    custom_rate DECIMAL(5, 2),                 -- Override scheme rate for this user

    -- Status
    is_active BOOLEAN DEFAULT TRUE,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    created_by UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- Constraints
    CONSTRAINT check_custom_rate_range CHECK (custom_rate IS NULL OR (custom_rate >= 0 AND custom_rate <= 100)),
    CONSTRAINT check_date_range CHECK (ends_at IS NULL OR ends_at > starts_at),
    CONSTRAINT unique_active_assignment UNIQUE (tenant_id, user_id, scheme_id, starts_at)
);

COMMENT ON TABLE commissions.assignments IS 'User to commission scheme assignments';
COMMENT ON COLUMN commissions.assignments.custom_rate IS 'Override rate for specific user (optional)';

-- ============================================
-- Commission Entries (generated commissions)
-- ============================================
CREATE TABLE commissions.entries (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Who earned the commission
    user_id UUID NOT NULL REFERENCES users.users(id) ON DELETE CASCADE,
    scheme_id UUID NOT NULL REFERENCES commissions.schemes(id) ON DELETE SET NULL,
    assignment_id UUID REFERENCES commissions.assignments(id) ON DELETE SET NULL,

    -- Reference to source transaction
    reference_type VARCHAR(50) NOT NULL,       -- 'sale', 'opportunity', 'order', etc.
    reference_id UUID NOT NULL,                -- ID of the source record

    -- Calculation details
    base_amount DECIMAL(15, 2) NOT NULL,       -- Original sale amount
    rate_applied DECIMAL(5, 2) NOT NULL,       -- Rate that was applied
    commission_amount DECIMAL(15, 2) NOT NULL, -- Calculated commission
    currency VARCHAR(3) DEFAULT 'USD',

    -- Status tracking
    status commissions.entry_status DEFAULT 'pending' NOT NULL,
    period_id UUID REFERENCES commissions.periods(id) ON DELETE SET NULL,

    -- Payment tracking
    paid_at TIMESTAMPTZ,
    payment_reference VARCHAR(255),            -- External payment reference

    -- Additional info
    notes TEXT,
    metadata JSONB DEFAULT '{}'::jsonb,        -- Extra data (product info, etc.)

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    approved_by UUID REFERENCES users.users(id) ON DELETE SET NULL,
    approved_at TIMESTAMPTZ,

    -- Constraints
    CONSTRAINT check_base_amount_positive CHECK (base_amount >= 0),
    CONSTRAINT check_rate_applied_range CHECK (rate_applied >= 0 AND rate_applied <= 100),
    CONSTRAINT check_commission_positive CHECK (commission_amount >= 0)
);

COMMENT ON TABLE commissions.entries IS 'Individual commission entries for transactions';
COMMENT ON COLUMN commissions.entries.reference_type IS 'Type of source record (sale, opportunity, order)';
COMMENT ON COLUMN commissions.entries.metadata IS 'Additional context data in JSON format';

-- ============================================
-- Commission Periods (payment cycles)
-- ============================================
CREATE TABLE commissions.periods (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Period identification
    name VARCHAR(100) NOT NULL,                -- e.g., "January 2026", "Week 1-2026"
    starts_at TIMESTAMPTZ NOT NULL,
    ends_at TIMESTAMPTZ NOT NULL,

    -- Aggregated totals (calculated on close)
    total_entries INT DEFAULT 0,
    total_amount DECIMAL(15, 2) DEFAULT 0,
    currency VARCHAR(3) DEFAULT 'USD',

    -- Status tracking
    status commissions.period_status DEFAULT 'open' NOT NULL,
    closed_at TIMESTAMPTZ,
    closed_by UUID REFERENCES users.users(id) ON DELETE SET NULL,
    paid_at TIMESTAMPTZ,
    paid_by UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- Payment info
    payment_reference VARCHAR(255),
    payment_notes TEXT,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    created_by UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- Constraints
    CONSTRAINT check_period_dates CHECK (ends_at > starts_at),
    CONSTRAINT unique_period_dates UNIQUE (tenant_id, starts_at, ends_at)
);

COMMENT ON TABLE commissions.periods IS 'Commission payment periods/cycles';
COMMENT ON COLUMN commissions.periods.name IS 'Human-readable period name';

-- ============================================
-- Triggers for updated_at
-- ============================================
CREATE OR REPLACE FUNCTION commissions.update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_schemes_updated_at
    BEFORE UPDATE ON commissions.schemes
    FOR EACH ROW
    EXECUTE FUNCTION commissions.update_updated_at();

CREATE TRIGGER trg_entries_updated_at
    BEFORE UPDATE ON commissions.entries
    FOR EACH ROW
    EXECUTE FUNCTION commissions.update_updated_at();
