-- ==========================================
-- Chat Switchboard — 010 Projects
-- ==========================================
-- Projects, junction tables, and cross-domain FK columns on
-- channels/projects for workspace/project bindings.
-- ICD §8 (Projects)
-- ==========================================

-- =========================================
-- PROJECTS
-- =========================================

CREATE TABLE IF NOT EXISTS projects (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name        VARCHAR(200) NOT NULL,
    description TEXT,
    color       VARCHAR(7),
    icon        VARCHAR(50),
    scope       VARCHAR(20) NOT NULL DEFAULT 'personal'
                CHECK (scope IN ('personal', 'team', 'global')),
    owner_id    UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    team_id     UUID REFERENCES teams(id) ON DELETE SET NULL,
    workspace_id UUID REFERENCES workspaces(id) ON DELETE SET NULL,
    is_archived BOOLEAN NOT NULL DEFAULT false,
    settings    JSONB DEFAULT '{}'::jsonb,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    updated_at  TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_projects_owner ON projects(owner_id);
CREATE INDEX IF NOT EXISTS idx_projects_team  ON projects(team_id) WHERE team_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_projects_scope ON projects(scope);
CREATE INDEX IF NOT EXISTS idx_projects_workspace ON projects(workspace_id) WHERE workspace_id IS NOT NULL;

DROP TRIGGER IF EXISTS projects_updated_at ON projects;
CREATE TRIGGER projects_updated_at BEFORE UPDATE ON projects
    FOR EACH ROW EXECUTE FUNCTION update_updated_at();

COMMENT ON TABLE projects IS 'Organizes channels, KBs, and notes into named workspaces';
COMMENT ON COLUMN projects.scope IS 'personal=owner only, team=team members, global=all users';


-- =========================================
-- PROJECT ↔ CHANNEL JUNCTION
-- =========================================

CREATE TABLE IF NOT EXISTS project_channels (
    project_id  UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    channel_id  UUID NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    position    INTEGER NOT NULL DEFAULT 0,
    folder      TEXT,
    added_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (project_id, channel_id),
    UNIQUE (channel_id)
);

CREATE INDEX IF NOT EXISTS idx_project_channels_project  ON project_channels(project_id);
CREATE INDEX IF NOT EXISTS idx_project_channels_channel  ON project_channels(channel_id);

COMMENT ON TABLE project_channels IS 'Links channels to projects. UNIQUE(channel_id) enforces one-project-per-channel.';


-- =========================================
-- PROJECT ↔ KB JUNCTION
-- =========================================

CREATE TABLE IF NOT EXISTS project_knowledge_bases (
    project_id  UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    kb_id       UUID NOT NULL REFERENCES knowledge_bases(id) ON DELETE CASCADE,
    auto_search BOOLEAN NOT NULL DEFAULT false,
    added_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (project_id, kb_id)
);

CREATE INDEX IF NOT EXISTS idx_project_kb_project ON project_knowledge_bases(project_id);
CREATE INDEX IF NOT EXISTS idx_project_kb_kb      ON project_knowledge_bases(kb_id);


-- =========================================
-- PROJECT ↔ NOTE JUNCTION
-- =========================================

CREATE TABLE IF NOT EXISTS project_notes (
    project_id  UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    note_id     UUID NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
    added_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (project_id, note_id)
);

CREATE INDEX IF NOT EXISTS idx_project_notes_project ON project_notes(project_id);
CREATE INDEX IF NOT EXISTS idx_project_notes_note    ON project_notes(note_id);


-- =========================================
-- CROSS-DOMAIN FK COLUMNS
-- =========================================
-- Deferred FKs: channels.project_id and workspace_id declared in 005
-- without FK constraints (referenced tables didn't exist yet).

DO $$ BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'fk_channels_project'
    ) THEN
        ALTER TABLE channels ADD CONSTRAINT fk_channels_project
            FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL;
    END IF;
END $$;

DO $$ BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint WHERE conname = 'fk_channels_workspace'
    ) THEN
        ALTER TABLE channels ADD CONSTRAINT fk_channels_workspace
            FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE SET NULL;
    END IF;
END $$;


-- =========================================
-- FOLDER → PROJECT MIGRATION (idempotent)
-- =========================================
-- Best-effort migration of legacy folder values into projects.
-- Only runs if there are channels with a folder value and no project_id.

DO $$
DECLARE
    _folder TEXT;
    _user_id UUID;
    _proj_id UUID;
    _ch_id UUID;
BEGIN
    FOR _user_id, _folder IN
        SELECT DISTINCT user_id, folder FROM channels
        WHERE folder IS NOT NULL AND folder != '' AND project_id IS NULL
    LOOP
        INSERT INTO projects (name, scope, owner_id)
        VALUES (_folder, 'personal', _user_id)
        RETURNING id INTO _proj_id;

        FOR _ch_id IN
            SELECT id FROM channels
            WHERE user_id = _user_id AND folder = _folder AND project_id IS NULL
        LOOP
            INSERT INTO project_channels (project_id, channel_id, position)
            VALUES (_proj_id, _ch_id, 0)
            ON CONFLICT DO NOTHING;

            UPDATE channels SET project_id = _proj_id WHERE id = _ch_id;
        END LOOP;
    END LOOP;
END
$$;
