package meta

import (
	"context"
	"database/sql"
	"fmt"
)

const metaSchemaSQL = `
CREATE SCHEMA IF NOT EXISTS platform_meta;

CREATE TABLE IF NOT EXISTS platform_meta.tenants (
    tenant_id   BIGSERIAL PRIMARY KEY,
    name        VARCHAR(128) NOT NULL,
    slug        VARCHAR(64) NOT NULL DEFAULT '',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS platform_meta.users (
    user_id       BIGSERIAL PRIMARY KEY,
    tenant_id     BIGINT REFERENCES platform_meta.tenants(tenant_id),
    username      VARCHAR(64) NOT NULL,
    password_hash TEXT NOT NULL,
    display_name  VARCHAR(128) NOT NULL DEFAULT '',
    role          VARCHAR(32) NOT NULL DEFAULT 'pending',
    status        VARCHAR(32) NOT NULL DEFAULT 'pending',
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_users_username UNIQUE (username)
);

CREATE INDEX IF NOT EXISTS idx_users_tenant ON platform_meta.users (tenant_id);

-- 兼容旧库：允许无租户（pending）
ALTER TABLE platform_meta.users ALTER COLUMN tenant_id DROP NOT NULL;
ALTER TABLE platform_meta.users ADD COLUMN IF NOT EXISTS status VARCHAR(32) NOT NULL DEFAULT 'active';

CREATE TABLE IF NOT EXISTS platform_meta.tenant_apps (
    app_id         UUID PRIMARY KEY,
    tenant_id      BIGINT NOT NULL,
    slug           VARCHAR(64) NOT NULL,
    name           VARCHAR(128) NOT NULL,
    schema_name    VARCHAR(64) NOT NULL,
    engine         VARCHAR(32) NOT NULL,
    status         VARCHAR(32) NOT NULL,
    blueprint_json JSONB NOT NULL,
    ddl_json       JSONB NOT NULL DEFAULT '[]'::jsonb,
    endpoints_json JSONB NOT NULL DEFAULT '[]'::jsonb,
    error_msg      TEXT NOT NULL DEFAULT '',
    created_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_tenant_apps_tenant_slug UNIQUE (tenant_id, slug)
);

CREATE INDEX IF NOT EXISTS idx_tenant_apps_tenant_status
    ON platform_meta.tenant_apps (tenant_id, status);

ALTER TABLE platform_meta.tenant_apps
    ADD COLUMN IF NOT EXISTS database_name VARCHAR(64) NOT NULL DEFAULT '';

CREATE TABLE IF NOT EXISTS platform_meta.audit_logs (
    id         BIGSERIAL PRIMARY KEY,
    tenant_id  BIGINT NOT NULL,
    user_id    BIGINT NOT NULL,
    action     VARCHAR(64) NOT NULL,
    detail     TEXT NOT NULL DEFAULT '',
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 智能体服务账号（机器身份，供宿主自动登录）
CREATE TABLE IF NOT EXISTS platform_meta.agent_accounts (
    agent_id           BIGSERIAL PRIMARY KEY,
    tenant_id          BIGINT NOT NULL REFERENCES platform_meta.tenants(tenant_id),
    name               VARCHAR(128) NOT NULL,
    client_id          VARCHAR(64) NOT NULL,
    client_secret_hash TEXT NOT NULL,
    status             VARCHAR(32) NOT NULL DEFAULT 'active',
    created_by         BIGINT NOT NULL DEFAULT 0,
    created_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
    last_token_at      TIMESTAMPTZ,
    CONSTRAINT uq_agent_client_id UNIQUE (client_id)
);

CREATE INDEX IF NOT EXISTS idx_agent_accounts_tenant
    ON platform_meta.agent_accounts (tenant_id);

ALTER TABLE platform_meta.agent_accounts
    ADD COLUMN IF NOT EXISTS host_key VARCHAR(128) NOT NULL DEFAULT '';

CREATE UNIQUE INDEX IF NOT EXISTS uq_agent_tenant_host_key
    ON platform_meta.agent_accounts (tenant_id, host_key)
    WHERE host_key <> '';

CREATE TABLE IF NOT EXISTS platform_meta.agent_permissions (
    agent_id BIGINT NOT NULL REFERENCES platform_meta.agent_accounts(agent_id) ON DELETE CASCADE,
    perm     VARCHAR(64) NOT NULL,
    PRIMARY KEY (agent_id, perm)
);

CREATE TABLE IF NOT EXISTS platform_meta.agent_app_grants (
    agent_id BIGINT NOT NULL REFERENCES platform_meta.agent_accounts(agent_id) ON DELETE CASCADE,
    slug     VARCHAR(64) NOT NULL,
    PRIMARY KEY (agent_id, slug)
);

-- 可编辑角色（租户级）
CREATE TABLE IF NOT EXISTS platform_meta.roles (
    role_id     BIGSERIAL PRIMARY KEY,
    tenant_id   BIGINT NOT NULL REFERENCES platform_meta.tenants(tenant_id),
    code        VARCHAR(64) NOT NULL,
    name        VARCHAR(128) NOT NULL,
    description TEXT NOT NULL DEFAULT '',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_roles_tenant_code UNIQUE (tenant_id, code)
);

CREATE INDEX IF NOT EXISTS idx_roles_tenant ON platform_meta.roles (tenant_id);

CREATE TABLE IF NOT EXISTS platform_meta.role_permissions (
    role_id BIGINT NOT NULL REFERENCES platform_meta.roles(role_id) ON DELETE CASCADE,
    perm    VARCHAR(64) NOT NULL,
    PRIMARY KEY (role_id, perm)
);

ALTER TABLE platform_meta.agent_accounts
    ADD COLUMN IF NOT EXISTS role_id BIGINT;

-- Z8b：智能体绑定同步通道 / 线上库 / 模块落库名
ALTER TABLE platform_meta.agent_accounts
    ADD COLUMN IF NOT EXISTS channel_id VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE platform_meta.agent_accounts
    ADD COLUMN IF NOT EXISTS online_db_id VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE platform_meta.agent_accounts
    ADD COLUMN IF NOT EXISTS database_name VARCHAR(128) NOT NULL DEFAULT '';

-- 租户邀请码：pending 用户凭码加入已有公司
CREATE TABLE IF NOT EXISTS platform_meta.tenant_invites (
    invite_id   BIGSERIAL PRIMARY KEY,
    tenant_id   BIGINT NOT NULL REFERENCES platform_meta.tenants(tenant_id) ON DELETE CASCADE,
    code        VARCHAR(64) NOT NULL,
    role        VARCHAR(32) NOT NULL DEFAULT 'editor',
    created_by  BIGINT NOT NULL DEFAULT 0,
    max_uses    INT NOT NULL DEFAULT 1,
    used_count  INT NOT NULL DEFAULT 0,
    status      VARCHAR(32) NOT NULL DEFAULT 'active',
    expires_at  TIMESTAMPTZ,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT uq_tenant_invites_code UNIQUE (code)
);

CREATE INDEX IF NOT EXISTS idx_tenant_invites_tenant
    ON platform_meta.tenant_invites (tenant_id);

-- 租户内多级组织（默认最多 5 级）
CREATE TABLE IF NOT EXISTS platform_meta.org_units (
    org_unit_id BIGSERIAL PRIMARY KEY,
    tenant_id   BIGINT NOT NULL REFERENCES platform_meta.tenants(tenant_id) ON DELETE CASCADE,
    parent_id   BIGINT REFERENCES platform_meta.org_units(org_unit_id) ON DELETE CASCADE,
    name        VARCHAR(128) NOT NULL,
    code        VARCHAR(64) NOT NULL DEFAULT '',
    depth       INT NOT NULL DEFAULT 1,
    path        VARCHAR(512) NOT NULL DEFAULT '',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_org_units_tenant_parent
    ON platform_meta.org_units (tenant_id, parent_id);

CREATE INDEX IF NOT EXISTS idx_org_units_tenant_path
    ON platform_meta.org_units (tenant_id, path);

CREATE UNIQUE INDEX IF NOT EXISTS uq_org_units_tenant_code
    ON platform_meta.org_units (tenant_id, code)
    WHERE code <> '';

ALTER TABLE platform_meta.users
    ADD COLUMN IF NOT EXISTS org_unit_id BIGINT;

ALTER TABLE platform_meta.tenant_invites
    ADD COLUMN IF NOT EXISTS org_unit_id BIGINT NOT NULL DEFAULT 0;

ALTER TABLE platform_meta.users
    ALTER COLUMN role TYPE VARCHAR(64);

CREATE TABLE IF NOT EXISTS platform_meta.tenant_permissions (
    tenant_id BIGINT NOT NULL REFERENCES platform_meta.tenants(tenant_id) ON DELETE CASCADE,
    perm      VARCHAR(64) NOT NULL,
    PRIMARY KEY (tenant_id, perm)
);

CREATE TABLE IF NOT EXISTS platform_meta.tenant_entitlement_state (
    tenant_id  BIGINT PRIMARY KEY REFERENCES platform_meta.tenants(tenant_id) ON DELETE CASCADE,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 公司路径 slug（www.example.com/{slug}/）；旧库补列
ALTER TABLE platform_meta.tenants ADD COLUMN IF NOT EXISTS slug VARCHAR(64) NOT NULL DEFAULT '';
CREATE UNIQUE INDEX IF NOT EXISTS uq_tenants_slug ON platform_meta.tenants (slug) WHERE slug <> '';

-- 手机号（可绑定；非空时全局唯一，可用于登录）
ALTER TABLE platform_meta.users ADD COLUMN IF NOT EXISTS phone VARCHAR(20) NOT NULL DEFAULT '';
CREATE UNIQUE INDEX IF NOT EXISTS uq_users_phone ON platform_meta.users (phone) WHERE phone <> '';

-- 已绑手机时可禁用用户名登录（仅手机号+密码/短信）
ALTER TABLE platform_meta.users ADD COLUMN IF NOT EXISTS username_login_disabled BOOLEAN NOT NULL DEFAULT false;

-- 授权租约已消费 id（删 leases 目录后仍能拦截旧延期包）
CREATE TABLE IF NOT EXISTS platform_meta.license_consumed (
    lease_id   VARCHAR(64) PRIMARY KEY,
    active     BOOLEAN NOT NULL DEFAULT false,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_license_consumed_active ON platform_meta.license_consumed (active) WHERE active;
`

// EnsureSchema 创建平台元数据表（幂等）。
func EnsureSchema(ctx context.Context, db *sql.DB) error {
	if db == nil {
		return fmt.Errorf("db is nil")
	}
	if _, err := db.ExecContext(ctx, metaSchemaSQL); err != nil {
		return fmt.Errorf("meta migrate: %w", err)
	}
	return nil
}
