-- ============================================================================
-- Teams Schema: Team Members Table
-- Manages team/organization membership
-- ============================================================================

-- Create teams schema if not exists
CREATE SCHEMA IF NOT EXISTS teams;

-- Grant usage
GRANT USAGE ON SCHEMA teams TO trading_user;

-- ============================================================================
-- TEAM_MEMBERS TABLE
-- Tracks membership status and details for users in a tenant
-- ============================================================================

CREATE TABLE IF NOT EXISTS teams.team_members (
    -- Primary key
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Tenant relationship
    tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,

    -- User relationship
    user_id UUID NOT NULL REFERENCES users.users(id) ON DELETE CASCADE,

    -- Membership status
    status VARCHAR(20) NOT NULL DEFAULT 'active'
        CHECK (status IN ('pending', 'active', 'suspended', 'removed')),

    -- Member type
    member_type VARCHAR(20) NOT NULL DEFAULT 'member'
        CHECK (member_type IN ('owner', 'admin', 'member', 'guest')),

    -- Join information
    joined_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    invited_by UUID REFERENCES users.users(id),
    invitation_id UUID, -- Reference to invitation (if joined via invite)

    -- Department/Team within organization
    department VARCHAR(100),
    job_title VARCHAR(100),

    -- Member settings
    settings JSONB NOT NULL DEFAULT '{}'::jsonb,

    -- Notification preferences for team
    notifications_enabled BOOLEAN NOT NULL DEFAULT true,

    -- Audit fields
    created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    removed_at TIMESTAMPTZ,
    removed_by UUID REFERENCES users.users(id),
    removal_reason TEXT,

    -- Constraints
    CONSTRAINT uq_team_member UNIQUE (tenant_id, user_id)
);

-- ============================================================================
-- INDEXES
-- ============================================================================

CREATE INDEX IF NOT EXISTS idx_team_members_tenant_id ON teams.team_members(tenant_id);
CREATE INDEX IF NOT EXISTS idx_team_members_user_id ON teams.team_members(user_id);
CREATE INDEX IF NOT EXISTS idx_team_members_status ON teams.team_members(status);
CREATE INDEX IF NOT EXISTS idx_team_members_member_type ON teams.team_members(member_type);
CREATE INDEX IF NOT EXISTS idx_team_members_department ON teams.team_members(tenant_id, department);
CREATE INDEX IF NOT EXISTS idx_team_members_joined_at ON teams.team_members(joined_at);

-- ============================================================================
-- ROW LEVEL SECURITY
-- ============================================================================

ALTER TABLE teams.team_members ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only see members in their tenant
CREATE POLICY team_members_tenant_isolation ON teams.team_members
    FOR ALL
    USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

-- ============================================================================
-- TRIGGERS
-- ============================================================================

-- Auto-update updated_at timestamp
CREATE OR REPLACE FUNCTION teams.update_team_members_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_team_members_updated_at
    BEFORE UPDATE ON teams.team_members
    FOR EACH ROW
    EXECUTE FUNCTION teams.update_team_members_timestamp();

-- ============================================================================
-- VIEW: Team members with user details
-- ============================================================================

CREATE OR REPLACE VIEW teams.v_team_members AS
SELECT
    tm.id,
    tm.tenant_id,
    tm.user_id,
    u.email,
    u.first_name,
    u.last_name,
    u.display_name,
    u.avatar_url,
    u.status AS user_status,
    tm.status AS membership_status,
    tm.member_type,
    tm.department,
    tm.job_title,
    tm.joined_at,
    tm.notifications_enabled,
    inviter.email AS invited_by_email,
    inviter.display_name AS invited_by_name,
    -- Get primary role
    (
        SELECT r.name
        FROM rbac.user_roles ur
        JOIN rbac.roles r ON ur.role_id = r.id
        WHERE ur.user_id = tm.user_id
          AND ur.tenant_id = tm.tenant_id
          AND ur.is_primary = true
          AND ur.is_active = true
        LIMIT 1
    ) AS primary_role
FROM teams.team_members tm
JOIN users.users u ON tm.user_id = u.id
LEFT JOIN users.users inviter ON tm.invited_by = inviter.id
WHERE tm.status != 'removed';

-- ============================================================================
-- FUNCTION: Add user to team
-- ============================================================================

CREATE OR REPLACE FUNCTION teams.add_team_member(
    p_tenant_id UUID,
    p_user_id UUID,
    p_member_type VARCHAR(20) DEFAULT 'member',
    p_invited_by UUID DEFAULT NULL,
    p_invitation_id UUID DEFAULT NULL,
    p_department VARCHAR(100) DEFAULT NULL,
    p_job_title VARCHAR(100) DEFAULT NULL
)
RETURNS UUID AS $$
DECLARE
    v_member_id UUID;
BEGIN
    INSERT INTO teams.team_members (
        tenant_id, user_id, member_type, invited_by,
        invitation_id, department, job_title, status
    ) VALUES (
        p_tenant_id, p_user_id, p_member_type, p_invited_by,
        p_invitation_id, p_department, p_job_title, 'active'
    )
    ON CONFLICT (tenant_id, user_id) DO UPDATE SET
        status = 'active',
        member_type = EXCLUDED.member_type,
        department = COALESCE(EXCLUDED.department, teams.team_members.department),
        job_title = COALESCE(EXCLUDED.job_title, teams.team_members.job_title),
        removed_at = NULL,
        removed_by = NULL,
        removal_reason = NULL,
        updated_at = CURRENT_TIMESTAMP
    RETURNING id INTO v_member_id;

    RETURN v_member_id;
END;
$$ LANGUAGE plpgsql;

-- ============================================================================
-- FUNCTION: Remove user from team
-- ============================================================================

CREATE OR REPLACE FUNCTION teams.remove_team_member(
    p_tenant_id UUID,
    p_user_id UUID,
    p_removed_by UUID,
    p_reason TEXT DEFAULT NULL
)
RETURNS BOOLEAN AS $$
BEGIN
    UPDATE teams.team_members
    SET
        status = 'removed',
        removed_at = CURRENT_TIMESTAMP,
        removed_by = p_removed_by,
        removal_reason = p_reason,
        updated_at = CURRENT_TIMESTAMP
    WHERE tenant_id = p_tenant_id
      AND user_id = p_user_id
      AND status = 'active';

    RETURN FOUND;
END;
$$ LANGUAGE plpgsql;

-- ============================================================================
-- GRANTS
-- ============================================================================

GRANT SELECT, INSERT, UPDATE, DELETE ON teams.team_members TO trading_user;
GRANT SELECT ON teams.v_team_members TO trading_user;
GRANT EXECUTE ON FUNCTION teams.add_team_member TO trading_user;
GRANT EXECUTE ON FUNCTION teams.remove_team_member TO trading_user;

-- ============================================================================
-- COMMENTS
-- ============================================================================

COMMENT ON TABLE teams.team_members IS 'Tracks team/organization membership for users';
COMMENT ON COLUMN teams.team_members.member_type IS 'Type of membership: owner, admin, member, guest';
COMMENT ON COLUMN teams.team_members.settings IS 'JSON settings for member-specific preferences';
COMMENT ON VIEW teams.v_team_members IS 'Team members with user details and primary role';
