-- ============================================
-- TEMPLATE-SAAS: Sales Tables
-- Version: 1.0.0
-- Module: SAAS-018
-- ============================================

-- ============================================
-- Pipeline Stages (configurable stages per tenant)
-- ============================================
CREATE TABLE sales.pipeline_stages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Stage info
    name VARCHAR(100) NOT NULL,
    position INT NOT NULL DEFAULT 0,
    color VARCHAR(7) DEFAULT '#3B82F6',

    -- Stage type flags
    is_won BOOLEAN DEFAULT FALSE,
    is_lost BOOLEAN DEFAULT FALSE,
    is_active BOOLEAN DEFAULT TRUE,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,

    -- Constraints
    CONSTRAINT unique_stage_position UNIQUE (tenant_id, position),
    CONSTRAINT check_win_lost_exclusive CHECK (NOT (is_won AND is_lost))
);

COMMENT ON TABLE sales.pipeline_stages IS 'Configurable pipeline stages per tenant';

-- ============================================
-- Leads (prospects)
-- ============================================
CREATE TABLE sales.leads (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Contact info
    first_name VARCHAR(100) NOT NULL,
    last_name VARCHAR(100) NOT NULL,
    email VARCHAR(255),
    phone VARCHAR(50),

    -- Company info
    company VARCHAR(200),
    job_title VARCHAR(150),
    website VARCHAR(255),

    -- Lead classification
    source sales.lead_source DEFAULT 'other',
    status sales.lead_status DEFAULT 'new' NOT NULL,
    score INT DEFAULT 0 CHECK (score >= 0 AND score <= 100),

    -- Assignment
    assigned_to UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- Notes
    notes TEXT,

    -- Conversion tracking
    converted_at TIMESTAMPTZ,
    converted_to_opportunity_id UUID,

    -- Address
    address_line1 VARCHAR(255),
    address_line2 VARCHAR(255),
    city VARCHAR(100),
    state VARCHAR(100),
    postal_code VARCHAR(20),
    country VARCHAR(100),

    -- Custom fields (JSON)
    custom_fields JSONB DEFAULT '{}'::jsonb,

    -- 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
);

COMMENT ON TABLE sales.leads IS 'Sales leads/prospects';
COMMENT ON COLUMN sales.leads.score IS 'Lead score from 0-100';
COMMENT ON COLUMN sales.leads.custom_fields IS 'Flexible custom fields per tenant';

-- ============================================
-- Opportunities (deals)
-- ============================================
CREATE TABLE sales.opportunities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

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

    -- Lead reference (optional)
    lead_id UUID REFERENCES sales.leads(id) ON DELETE SET NULL,

    -- Pipeline stage
    stage sales.opportunity_stage DEFAULT 'prospecting' NOT NULL,
    stage_id UUID REFERENCES sales.pipeline_stages(id) ON DELETE SET NULL,

    -- Value
    amount DECIMAL(15, 2) DEFAULT 0,
    currency VARCHAR(3) DEFAULT 'USD',
    probability INT DEFAULT 0 CHECK (probability >= 0 AND probability <= 100),

    -- Timeline
    expected_close_date DATE,
    actual_close_date DATE,

    -- Assignment
    assigned_to UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- Win/Loss tracking
    won_at TIMESTAMPTZ,
    lost_at TIMESTAMPTZ,
    lost_reason VARCHAR(500),

    -- Contact info (can be different from lead)
    contact_name VARCHAR(200),
    contact_email VARCHAR(255),
    contact_phone VARCHAR(50),
    company_name VARCHAR(200),

    -- Notes
    notes TEXT,

    -- Custom fields
    custom_fields JSONB DEFAULT '{}'::jsonb,

    -- 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_close_status CHECK (
        (won_at IS NULL OR lost_at IS NULL) -- Cannot be both won and lost
    )
);

COMMENT ON TABLE sales.opportunities IS 'Sales opportunities/deals';
COMMENT ON COLUMN sales.opportunities.probability IS 'Win probability percentage (0-100)';

-- ============================================
-- Activities (calls, meetings, tasks, etc.)
-- ============================================
CREATE TABLE sales.activities (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- Activity type
    type sales.activity_type NOT NULL,
    status sales.activity_status DEFAULT 'pending' NOT NULL,

    -- Content
    subject VARCHAR(255) NOT NULL,
    description TEXT,

    -- Related records (at least one should be set)
    lead_id UUID REFERENCES sales.leads(id) ON DELETE CASCADE,
    opportunity_id UUID REFERENCES sales.opportunities(id) ON DELETE CASCADE,

    -- Scheduling
    due_date TIMESTAMPTZ,
    due_time TIME,
    duration_minutes INT,

    -- Completion
    completed_at TIMESTAMPTZ,
    outcome TEXT,

    -- Assignment
    assigned_to UUID REFERENCES users.users(id) ON DELETE SET NULL,
    created_by UUID REFERENCES users.users(id) ON DELETE SET NULL,

    -- For calls
    call_direction VARCHAR(10), -- 'inbound' or 'outbound'
    call_recording_url VARCHAR(500),

    -- For meetings
    location VARCHAR(255),
    meeting_url VARCHAR(500),
    attendees JSONB DEFAULT '[]'::jsonb,

    -- Reminder
    reminder_at TIMESTAMPTZ,
    reminder_sent BOOLEAN DEFAULT FALSE,

    -- Custom fields
    custom_fields JSONB DEFAULT '{}'::jsonb,

    -- Audit
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    deleted_at TIMESTAMPTZ,

    -- Constraints
    CONSTRAINT check_related_record CHECK (
        lead_id IS NOT NULL OR opportunity_id IS NOT NULL
    )
);

COMMENT ON TABLE sales.activities IS 'Sales activities: calls, meetings, tasks, emails, notes';
COMMENT ON COLUMN sales.activities.attendees IS 'JSON array of meeting attendees';

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

CREATE TRIGGER trg_pipeline_stages_updated_at
    BEFORE UPDATE ON sales.pipeline_stages
    FOR EACH ROW
    EXECUTE FUNCTION sales.update_updated_at();

CREATE TRIGGER trg_leads_updated_at
    BEFORE UPDATE ON sales.leads
    FOR EACH ROW
    EXECUTE FUNCTION sales.update_updated_at();

CREATE TRIGGER trg_opportunities_updated_at
    BEFORE UPDATE ON sales.opportunities
    FOR EACH ROW
    EXECUTE FUNCTION sales.update_updated_at();

CREATE TRIGGER trg_activities_updated_at
    BEFORE UPDATE ON sales.activities
    FOR EACH ROW
    EXECUTE FUNCTION sales.update_updated_at();
