-- +goose Up
-- +goose StatementBegin
CREATE TABLE IF NOT EXISTS media_assets(
    id bigserial PRIMARY KEY,
    tenant_id bigint NOT NULL,
    user_id bigint NOT NULL,
    type varchar(32) NOT NULL DEFAULT 'video',
    status varchar(32) NOT NULL DEFAULT 'uploaded',
    provider varchar(64) NOT NULL DEFAULT '',
    bucket varchar(128) NOT NULL DEFAULT '',
    object_key varchar(512) NOT NULL DEFAULT '',
    meta jsonb NOT NULL DEFAULT '{}'::jsonb,
    deleted_at timestamptz,
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW()
);

-- media_assets：媒体资源表（视频/音频/图片），用于承载实际文件对象及其处理状态
COMMENT ON TABLE media_assets IS '媒体资源：存储对象的抽象（video/audio/image），关联租户与上传用户，记录处理状态与元数据';
COMMENT ON COLUMN media_assets.id IS '主键ID：自增；仅用于内部关联';
COMMENT ON COLUMN media_assets.tenant_id IS '租户ID：多租户隔离关键字段；所有查询/写入必须限定 tenant_id';
COMMENT ON COLUMN media_assets.user_id IS '用户ID：资源上传者；用于审计与权限控制';
COMMENT ON COLUMN media_assets.type IS '资源类型：video/audio/image；决定后续处理流程（转码/缩略图/封面等）';
COMMENT ON COLUMN media_assets.status IS '处理状态：uploaded/processing/ready/failed/deleted；ready 才可被内容引用对外提供';
COMMENT ON COLUMN media_assets.provider IS '存储提供方：例如 s3/minio/oss；便于多存储扩展';
COMMENT ON COLUMN media_assets.bucket IS '存储桶：对象所在 bucket；与 provider 组合确定存储定位';
COMMENT ON COLUMN media_assets.object_key IS '对象键：对象在 bucket 内的 key；不得暴露可长期复用的直链（通过签名URL/token下发）';
COMMENT ON COLUMN media_assets.meta IS '元数据：JSON；包含 hash、duration、width、height、bitrate、codec 等；用于展示与计费/风控';
COMMENT ON COLUMN media_assets.deleted_at IS '软删除时间：非空表示已删除；对外接口需过滤';
COMMENT ON COLUMN media_assets.created_at IS '创建时间：默认 now()；用于审计与排序';
COMMENT ON COLUMN media_assets.updated_at IS '更新时间：默认 now()；更新状态/元数据时写入';

CREATE INDEX IF NOT EXISTS ix_media_assets_tenant_id ON media_assets(tenant_id);
CREATE INDEX IF NOT EXISTS ix_media_assets_tenant_user_id ON media_assets(tenant_id, user_id);
CREATE INDEX IF NOT EXISTS ix_media_assets_tenant_status ON media_assets(tenant_id, status);

CREATE TABLE IF NOT EXISTS contents(
    id bigserial PRIMARY KEY,
    tenant_id bigint NOT NULL,
    user_id bigint NOT NULL,
    title varchar(255) NOT NULL DEFAULT '',
    description text NOT NULL DEFAULT '',
    status varchar(32) NOT NULL DEFAULT 'draft',
    visibility varchar(32) NOT NULL DEFAULT 'tenant_only',
    preview_seconds int NOT NULL DEFAULT 60,
    preview_downloadable boolean NOT NULL DEFAULT false,
    published_at timestamptz,
    deleted_at timestamptz,
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW()
);

-- contents：内容表（可发布/可售卖/可试看）
COMMENT ON TABLE contents IS '内容：可发布的媒体内容实体，承载标题描述、可见性、试看配置、发布状态等';
COMMENT ON COLUMN contents.id IS '主键ID：自增；用于内容引用';
COMMENT ON COLUMN contents.tenant_id IS '租户ID：多租户隔离关键字段；所有查询/写入必须限定 tenant_id';
COMMENT ON COLUMN contents.user_id IS '用户ID：内容创建者/发布者；用于权限与审计（例如私有内容仅作者可见）';
COMMENT ON COLUMN contents.title IS '标题：用于列表展示与搜索；建议限制长度（由业务校验）';
COMMENT ON COLUMN contents.description IS '描述：用于详情页展示；可为空字符串';
COMMENT ON COLUMN contents.status IS '状态：draft/reviewing/published/unpublished/blocked；published 才对外展示';
COMMENT ON COLUMN contents.visibility IS '可见性：public/tenant_only/private；仅控制详情可见，正片资源仍需按价格/权益校验';
COMMENT ON COLUMN contents.preview_seconds IS '试看秒数：默认 60；只对 preview 资源生效；必须为正整数';
COMMENT ON COLUMN contents.preview_downloadable IS '试看是否允许下载：默认 false；当前策略固定为不允许下载（仅 streaming）';
COMMENT ON COLUMN contents.published_at IS '发布时间：首次发布时写入；用于时间窗与排序';
COMMENT ON COLUMN contents.deleted_at IS '软删除时间：非空表示已删除；对外接口需过滤';
COMMENT ON COLUMN contents.created_at IS '创建时间：默认 now()；用于审计与排序';
COMMENT ON COLUMN contents.updated_at IS '更新时间：默认 now()；编辑内容时写入';

CREATE INDEX IF NOT EXISTS ix_contents_tenant_id ON contents(tenant_id);
CREATE INDEX IF NOT EXISTS ix_contents_tenant_user_id ON contents(tenant_id, user_id);
CREATE INDEX IF NOT EXISTS ix_contents_tenant_status ON contents(tenant_id, status);
CREATE INDEX IF NOT EXISTS ix_contents_tenant_visibility ON contents(tenant_id, visibility);

CREATE TABLE IF NOT EXISTS content_assets(
    id bigserial PRIMARY KEY,
    tenant_id bigint NOT NULL,
    user_id bigint NOT NULL,
    content_id bigint NOT NULL,
    asset_id bigint NOT NULL,
    role varchar(32) NOT NULL DEFAULT 'main',
    sort int NOT NULL DEFAULT 0,
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW(),
    UNIQUE (tenant_id, content_id, asset_id)
);

-- content_assets：内容与媒体资源的关联（区分 main/cover/preview）
COMMENT ON TABLE content_assets IS '内容-资源关联：将 media_assets 以角色（main/cover/preview）绑定到 contents，支持排序';
COMMENT ON COLUMN content_assets.id IS '主键ID：自增';
COMMENT ON COLUMN content_assets.tenant_id IS '租户ID：多租户隔离；必须与 content_id、asset_id 所属租户一致';
COMMENT ON COLUMN content_assets.user_id IS '用户ID：操作人/绑定人；用于审计（通常为租户管理员或作者）';
COMMENT ON COLUMN content_assets.content_id IS '内容ID：关联 contents.id；用于查询内容下资源列表';
COMMENT ON COLUMN content_assets.asset_id IS '资源ID：关联 media_assets.id；用于查询资源归属内容';
COMMENT ON COLUMN content_assets.role IS '资源角色：main/cover/preview；preview 必须为独立资源以满足禁下载与防绕过';
COMMENT ON COLUMN content_assets.sort IS '排序：同一 role 下的展示顺序，数值越小越靠前';
COMMENT ON COLUMN content_assets.created_at IS '创建时间：默认 now()；用于审计';
COMMENT ON COLUMN content_assets.updated_at IS '更新时间：默认 now()；更新 sort/role 时写入';

CREATE INDEX IF NOT EXISTS ix_content_assets_tenant_content ON content_assets(tenant_id, content_id);
CREATE INDEX IF NOT EXISTS ix_content_assets_tenant_asset ON content_assets(tenant_id, asset_id);
CREATE INDEX IF NOT EXISTS ix_content_assets_tenant_role ON content_assets(tenant_id, content_id, role);

CREATE TABLE IF NOT EXISTS content_prices(
    id bigserial PRIMARY KEY,
    tenant_id bigint NOT NULL,
    user_id bigint NOT NULL,
    content_id bigint NOT NULL,
    currency varchar(16) NOT NULL DEFAULT 'CNY',
    price_amount bigint NOT NULL DEFAULT 0,
    discount_type varchar(16) NOT NULL DEFAULT 'none',
    discount_value bigint NOT NULL DEFAULT 0,
    discount_start_at timestamptz,
    discount_end_at timestamptz,
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW(),
    UNIQUE (tenant_id, content_id)
);

-- content_prices：内容定价与折扣（仅 CNY 分）
COMMENT ON TABLE content_prices IS '内容定价：为内容设置价格与折扣（订单需记录成交快照，避免改价影响历史）';
COMMENT ON COLUMN content_prices.id IS '主键ID：自增';
COMMENT ON COLUMN content_prices.tenant_id IS '租户ID：多租户隔离；与内容归属一致';
COMMENT ON COLUMN content_prices.user_id IS '用户ID：设置/更新价格的操作人（通常为 tenant_admin）；用于审计';
COMMENT ON COLUMN content_prices.content_id IS '内容ID：唯一约束 (tenant_id, content_id)；一个内容在一个租户内仅一份定价';
COMMENT ON COLUMN content_prices.currency IS '币种：当前固定 CNY；金额单位为分';
COMMENT ON COLUMN content_prices.price_amount IS '基础价格：分；0 表示免费（可直接访问正片资源）';
COMMENT ON COLUMN content_prices.discount_type IS '折扣类型：none/percent/amount；仅影响下单时成交价，需写入订单快照';
COMMENT ON COLUMN content_prices.discount_value IS '折扣值：percent=0-100（按业务校验）；amount=分；none 时忽略';
COMMENT ON COLUMN content_prices.discount_start_at IS '折扣开始时间：可为空；为空表示立即生效（由业务逻辑解释）';
COMMENT ON COLUMN content_prices.discount_end_at IS '折扣结束时间：可为空；为空表示长期有效（由业务逻辑解释）';
COMMENT ON COLUMN content_prices.created_at IS '创建时间：默认 now()；用于审计';
COMMENT ON COLUMN content_prices.updated_at IS '更新时间：默认 now()；更新价格/折扣时写入';

CREATE INDEX IF NOT EXISTS ix_content_prices_tenant_id ON content_prices(tenant_id);

CREATE TABLE IF NOT EXISTS content_access(
    id bigserial PRIMARY KEY,
    tenant_id bigint NOT NULL,
    user_id bigint NOT NULL,
    content_id bigint NOT NULL,
    order_id bigint,
    status varchar(16) NOT NULL DEFAULT 'active',
    revoked_at timestamptz,
    created_at timestamptz NOT NULL DEFAULT NOW(),
    updated_at timestamptz NOT NULL DEFAULT NOW(),
    UNIQUE (tenant_id, user_id, content_id)
);

-- content_access：购买权益/访问权限（退款后撤销）
COMMENT ON TABLE content_access IS '内容权益：记录用户在租户内对内容的访问资格；退款后应立即 revoked';
COMMENT ON COLUMN content_access.id IS '主键ID：自增';
COMMENT ON COLUMN content_access.tenant_id IS '租户ID：多租户隔离；与内容、用户归属一致';
COMMENT ON COLUMN content_access.user_id IS '用户ID：权益所属用户；用于访问校验';
COMMENT ON COLUMN content_access.content_id IS '内容ID：权益对应内容；唯一约束 (tenant_id, user_id, content_id)';
COMMENT ON COLUMN content_access.order_id IS '订单ID：产生该权益的订单；可为空（例如后台补发/迁移）';
COMMENT ON COLUMN content_access.status IS '权益状态：active/revoked/expired；revoked 表示立即失效（例如退款/违规）';
COMMENT ON COLUMN content_access.revoked_at IS '撤销时间：当 status=revoked 时写入；用于审计与追责';
COMMENT ON COLUMN content_access.created_at IS '创建时间：默认 now()；用于审计';
COMMENT ON COLUMN content_access.updated_at IS '更新时间：默认 now()；更新 status 时写入';

CREATE INDEX IF NOT EXISTS ix_content_access_tenant_user ON content_access(tenant_id, user_id);
CREATE INDEX IF NOT EXISTS ix_content_access_tenant_content ON content_access(tenant_id, content_id);

-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
DROP INDEX IF EXISTS ix_content_access_tenant_content;
DROP INDEX IF EXISTS ix_content_access_tenant_user;
DROP TABLE IF EXISTS content_access;

DROP INDEX IF EXISTS ix_content_prices_tenant_id;
DROP TABLE IF EXISTS content_prices;

DROP INDEX IF EXISTS ix_content_assets_tenant_role;
DROP INDEX IF EXISTS ix_content_assets_tenant_asset;
DROP INDEX IF EXISTS ix_content_assets_tenant_content;
DROP TABLE IF EXISTS content_assets;

DROP INDEX IF EXISTS ix_contents_tenant_visibility;
DROP INDEX IF EXISTS ix_contents_tenant_status;
DROP INDEX IF EXISTS ix_contents_tenant_user_id;
DROP INDEX IF EXISTS ix_contents_tenant_id;
DROP TABLE IF EXISTS contents;

DROP INDEX IF EXISTS ix_media_assets_tenant_status;
DROP INDEX IF EXISTS ix_media_assets_tenant_user_id;
DROP INDEX IF EXISTS ix_media_assets_tenant_id;
DROP TABLE IF EXISTS media_assets;

-- +goose StatementEnd
