-- Muse Content 模块初始 Schema（PostgreSQL 16）
-- 影响范围：作品、章节、Block、来源归因、导入导出任务。
-- 说明：业务表不使用数据库外键，引用完整性由应用层在权限、租户和 owner 校验后保证。

CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.update_time = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TABLE muse_content_work (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    owner_user_id BIGINT NOT NULL,
    title VARCHAR(200) NOT NULL,
    description TEXT,
    genre VARCHAR(50),
    cover_image_url TEXT,
    summary TEXT,
    status VARCHAR(20) NOT NULL DEFAULT 'writing',
    work_schema_id BIGINT,
    import_status VARCHAR(20),
    parse_status VARCHAR(20),
    word_count INT NOT NULL DEFAULT 0,
    chapter_count INT NOT NULL DEFAULT 0,
    command_id VARCHAR(120),
    revision INT NOT NULL DEFAULT 1,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0
);

CREATE INDEX idx_muse_content_work_owner ON muse_content_work(tenant_id, owner_user_id, update_time);
CREATE INDEX idx_muse_content_work_status ON muse_content_work(tenant_id, status);
CREATE UNIQUE INDEX uk_muse_content_work_command ON muse_content_work(tenant_id, command_id) WHERE command_id IS NOT NULL;
CREATE TRIGGER trg_muse_content_work_updated_at BEFORE UPDATE ON muse_content_work FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_chapter (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    work_id BIGINT NOT NULL,
    title VARCHAR(200) NOT NULL,
    order_no INT NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'draft',
    goal_snapshot JSONB,
    outline_snapshot JSONB,
    parse_review_status VARCHAR(20),
    command_id VARCHAR(120),
    revision INT NOT NULL DEFAULT 1,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_chapter_work_order UNIQUE (tenant_id, work_id, order_no)
);

CREATE INDEX idx_muse_content_chapter_work ON muse_content_chapter(tenant_id, work_id);
CREATE UNIQUE INDEX uk_muse_content_chapter_command ON muse_content_chapter(tenant_id, command_id) WHERE command_id IS NOT NULL;
CREATE TRIGGER trg_muse_content_chapter_updated_at BEFORE UPDATE ON muse_content_chapter FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_block (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    work_id BIGINT NOT NULL,
    chapter_id BIGINT NOT NULL,
    order_no INT NOT NULL,
    block_type VARCHAR(30) NOT NULL DEFAULT 'scene',
    title VARCHAR(500),
    content_doc JSONB,
    content_text TEXT,
    revision INT NOT NULL DEFAULT 1,
    word_count INT NOT NULL DEFAULT 0,
    command_id VARCHAR(120),
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_block_chapter_order UNIQUE (tenant_id, chapter_id, order_no)
);

CREATE INDEX idx_muse_content_block_work ON muse_content_block(tenant_id, work_id);
CREATE INDEX idx_muse_content_block_chapter ON muse_content_block(tenant_id, chapter_id);
CREATE UNIQUE INDEX uk_muse_content_block_command ON muse_content_block(tenant_id, command_id) WHERE command_id IS NOT NULL;
CREATE TRIGGER trg_muse_content_block_updated_at BEFORE UPDATE ON muse_content_block FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_block_source_attribution (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    work_id BIGINT NOT NULL,
    block_id BIGINT NOT NULL,
    revision INT NOT NULL,
    source_type VARCHAR(50) NOT NULL,
    source_object_id VARCHAR(100),
    source_version INT,
    lineage_payload JSONB,
    authorization_snapshot_id BIGINT,
    source_status VARCHAR(30),
    license_restriction_snapshot JSONB,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_block_src_revision UNIQUE (tenant_id, block_id, revision)
);

CREATE INDEX idx_muse_content_block_src_block ON muse_content_block_source_attribution(tenant_id, block_id);
CREATE TRIGGER trg_muse_content_block_src_updated_at BEFORE UPDATE ON muse_content_block_source_attribution FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_import_task (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    work_id BIGINT NOT NULL,
    owner_user_id BIGINT NOT NULL,
    source_type VARCHAR(50) NOT NULL,
    source_snapshot JSONB,
    status VARCHAR(30) NOT NULL DEFAULT 'queued',
    error_code VARCHAR(80),
    error_message TEXT,
    command_id VARCHAR(120) NOT NULL,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_import_command UNIQUE (tenant_id, command_id)
);

CREATE INDEX idx_muse_content_import_work ON muse_content_import_task(tenant_id, work_id, status);
CREATE TRIGGER trg_muse_content_import_updated_at BEFORE UPDATE ON muse_content_import_task FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_export_task (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    work_id BIGINT NOT NULL,
    owner_user_id BIGINT NOT NULL,
    export_format VARCHAR(30) NOT NULL,
    status VARCHAR(30) NOT NULL DEFAULT 'queued',
    credential_id VARCHAR(120),
    package_ref TEXT,
    error_code VARCHAR(80),
    error_message TEXT,
    command_id VARCHAR(120) NOT NULL,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_export_command UNIQUE (tenant_id, command_id)
);

CREATE INDEX idx_muse_content_export_work ON muse_content_export_task(tenant_id, work_id, status);
CREATE TRIGGER trg_muse_content_export_updated_at BEFORE UPDATE ON muse_content_export_task FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TABLE muse_content_command_log (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    command_id VARCHAR(120) NOT NULL,
    command_type VARCHAR(80) NOT NULL,
    owner_user_id BIGINT NOT NULL,
    target_type VARCHAR(50),
    target_id BIGINT,
    request_hash VARCHAR(128),
    result_snapshot JSONB,
    creator VARCHAR(64) NOT NULL DEFAULT '',
    create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater VARCHAR(64) NOT NULL DEFAULT '',
    update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted BOOLEAN NOT NULL DEFAULT FALSE,
    tenant_id BIGINT NOT NULL DEFAULT 0,
    CONSTRAINT uk_muse_content_command UNIQUE (tenant_id, command_id)
);

CREATE INDEX idx_muse_content_command_owner ON muse_content_command_log(tenant_id, owner_user_id, create_time);
CREATE TRIGGER trg_muse_content_command_updated_at BEFORE UPDATE ON muse_content_command_log FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
