-- +goose Up
-- Users
CREATE TABLE IF NOT EXISTS users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    roles TEXT[] DEFAULT '{user}',
    status VARCHAR(50) DEFAULT 'active',
    metas JSONB DEFAULT '{}',
    balance BIGINT DEFAULT 0,
    balance_frozen BIGINT DEFAULT 0,
    verified_at TIMESTAMP WITH TIME ZONE,
    
    -- New fields
    nickname VARCHAR(255) DEFAULT '',
    avatar VARCHAR(512) DEFAULT '',
    gender VARCHAR(32) DEFAULT 'secret',
    bio VARCHAR(512) DEFAULT '',
    birthday DATE,
    location JSONB DEFAULT '{}',
    points BIGINT DEFAULT 0,
    phone VARCHAR(32) DEFAULT '',
    is_real_name_verified BOOLEAN DEFAULT FALSE,

    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);

-- Tenants
CREATE TABLE IF NOT EXISTS tenants (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    code VARCHAR(64) NOT NULL UNIQUE,
    uuid UUID NOT NULL,
    name VARCHAR(128) NOT NULL,
    status VARCHAR(64) NOT NULL,
    config JSONB DEFAULT '{}',
    expired_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_tenants_user_id ON tenants(user_id);

-- TenantUsers
CREATE TABLE IF NOT EXISTS tenant_users (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    role TEXT[] DEFAULT '{member}',
    status VARCHAR(50) DEFAULT 'verified',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(tenant_id, user_id)
);

-- Contents
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,
    description TEXT NOT NULL,
    status VARCHAR(32) DEFAULT 'draft',
    visibility VARCHAR(32) DEFAULT 'tenant_only',
    preview_seconds INT DEFAULT 60,
    preview_downloadable BOOLEAN DEFAULT FALSE,
    published_at TIMESTAMP WITH TIME ZONE,
    summary VARCHAR(256) DEFAULT '',
    tags JSONB DEFAULT '[]',
    
    -- New fields
    body TEXT DEFAULT '',
    genre VARCHAR(64) DEFAULT '',
    views INT DEFAULT 0,
    likes INT DEFAULT 0,

    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);
CREATE INDEX IF NOT EXISTS idx_contents_tenant_id ON contents(tenant_id);

-- MediaAssets
CREATE TABLE IF NOT EXISTS media_assets (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    type VARCHAR(32) DEFAULT 'video',
    status VARCHAR(32) DEFAULT 'uploaded',
    provider VARCHAR(64) NOT NULL,
    bucket VARCHAR(128) NOT NULL,
    object_key VARCHAR(512) NOT NULL,
    meta JSONB DEFAULT '{}',
    variant VARCHAR(32) DEFAULT 'main',
    source_asset_id BIGINT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);

-- ContentAssets
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) DEFAULT 'main',
    sort INT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- ContentPrices
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) DEFAULT 'CNY',
    price_amount BIGINT NOT NULL,
    discount_type VARCHAR(16) DEFAULT 'none',
    discount_value BIGINT DEFAULT 0,
    discount_start_at TIMESTAMP WITH TIME ZONE,
    discount_end_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(tenant_id, content_id)
);

-- ContentAccess
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 DEFAULT 0,
    status VARCHAR(16) DEFAULT 'active',
    revoked_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(tenant_id, user_id, content_id)
);

-- Orders
CREATE TABLE IF NOT EXISTS orders (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    type VARCHAR(32) DEFAULT 'content_purchase',
    status VARCHAR(32) DEFAULT 'created',
    currency VARCHAR(16) DEFAULT 'CNY',
    amount_original BIGINT NOT NULL,
    amount_discount BIGINT NOT NULL,
    amount_paid BIGINT NOT NULL,
    snapshot JSONB DEFAULT '{}',
    idempotency_key VARCHAR(128) NOT NULL,
    paid_at TIMESTAMP WITH TIME ZONE,
    refunded_at TIMESTAMP WITH TIME ZONE,
    refund_forced BOOLEAN DEFAULT FALSE,
    refund_operator_user_id BIGINT DEFAULT 0,
    refund_reason VARCHAR(255) DEFAULT '',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- OrderItems
CREATE TABLE IF NOT EXISTS order_items (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    order_id BIGINT NOT NULL,
    content_id BIGINT NOT NULL,
    content_user_id BIGINT NOT NULL,
    amount_paid BIGINT NOT NULL,
    snapshot JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- TenantLedgers
CREATE TABLE IF NOT EXISTS tenant_ledgers (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    order_id BIGINT DEFAULT 0,
    type VARCHAR(32) NOT NULL,
    amount BIGINT NOT NULL,
    balance_before BIGINT NOT NULL,
    balance_after BIGINT NOT NULL,
    frozen_before BIGINT NOT NULL,
    frozen_after BIGINT NOT NULL,
    idempotency_key VARCHAR(128) NOT NULL,
    remark VARCHAR(255) NOT NULL,
    operator_user_id BIGINT DEFAULT 0,
    biz_ref_type VARCHAR(32) DEFAULT '',
    biz_ref_id BIGINT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- TenantInvites
CREATE TABLE IF NOT EXISTS tenant_invites (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    code VARCHAR(64) NOT NULL,
    status VARCHAR(32) DEFAULT 'active',
    max_uses INT NOT NULL,
    used_count INT DEFAULT 0,
    expires_at TIMESTAMP WITH TIME ZONE,
    disabled_at TIMESTAMP WITH TIME ZONE,
    disabled_operator_user_id BIGINT DEFAULT 0,
    remark VARCHAR(255) DEFAULT '',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- TenantJoinRequests
CREATE TABLE IF NOT EXISTS tenant_join_requests (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    status VARCHAR(32) DEFAULT 'pending',
    reason VARCHAR(255) NOT NULL,
    decided_at TIMESTAMP WITH TIME ZONE,
    decided_operator_user_id BIGINT DEFAULT 0,
    decided_reason VARCHAR(255) DEFAULT '',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Comments
CREATE TABLE IF NOT EXISTS comments (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    content_id BIGINT NOT NULL,
    reply_to BIGINT DEFAULT 0,
    content TEXT NOT NULL,
    likes INT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    deleted_at TIMESTAMP WITH TIME ZONE
);
CREATE INDEX IF NOT EXISTS idx_comments_content_id ON comments(content_id);
CREATE INDEX IF NOT EXISTS idx_comments_user_id ON comments(user_id);

-- User Content Actions (Like, Favorite)
CREATE TABLE IF NOT EXISTS user_content_actions (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    content_id BIGINT NOT NULL,
    type VARCHAR(32) NOT NULL, -- like, favorite
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(user_id, content_id, type)
);

-- User Comment Actions (Like)
CREATE TABLE IF NOT EXISTS user_comment_actions (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    comment_id BIGINT NOT NULL,
    type VARCHAR(32) NOT NULL, -- like
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(user_id, comment_id, type)
);

-- Payout Accounts
CREATE TABLE IF NOT EXISTS payout_accounts (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL, -- Associated with a creator tenant
    user_id BIGINT NOT NULL,   -- Creator user
    type VARCHAR(32) NOT NULL, -- bank, alipay
    name VARCHAR(128) NOT NULL,
    account VARCHAR(128) NOT NULL,
    realname VARCHAR(128) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_payout_accounts_tenant_id ON payout_accounts(tenant_id);

-- Notifications
CREATE TABLE IF NOT EXISTS notifications (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    tenant_id BIGINT DEFAULT 0, -- Optional source tenant
    type VARCHAR(32) NOT NULL, -- system, order, audit, interaction
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    is_read BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);

-- +goose Down
-- Revert logic omitted for dev speed in this context