-- =============================================================================
-- 迁移脚本：创建 auth Schema 认证业务表
-- 日期：2026-02-25
-- 目标库：test_zqyy_app（通过 APP_DB_DSN 连接）
-- 说明：在 auth Schema 下创建用户认证系统所需的 8 张业务表：
--       users、user_applications、site_code_mapping、roles、permissions、
--       role_permissions、user_site_roles、user_assistant_binding
--       包含字段定义、约束、索引、外键。使用 IF NOT EXISTS 幂等语法。
-- 前提：auth Schema 已由 P1 迁移脚本创建
--       （2026-02-24__p1_create_auth_biz_schemas.sql）
-- 需求：1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10
-- =============================================================================

-- 确保 auth Schema 存在（幂等）
CREATE SCHEMA IF NOT EXISTS auth;

-- ---------------------------------------------------------------------------
-- 1. users — 微信用户主表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.users (
    id              SERIAL          PRIMARY KEY,
    wx_openid       VARCHAR(128)    NOT NULL,
    wx_union_id     VARCHAR(128),
    wx_avatar_url   VARCHAR(512),
    nickname        VARCHAR(50),
    phone           VARCHAR(20),
    status          VARCHAR(20)     NOT NULL DEFAULT 'pending',
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

-- wx_openid 唯一约束（幂等：先检查再添加）
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_users_wx_openid' AND conrelid = 'auth.users'::regclass
    ) THEN
        ALTER TABLE auth.users ADD CONSTRAINT uq_users_wx_openid UNIQUE (wx_openid);
    END IF;
END $$;

-- 索引
CREATE INDEX IF NOT EXISTS ix_users_wx_openid ON auth.users (wx_openid);

-- ---------------------------------------------------------------------------
-- 2. site_code_mapping — 球房ID与门店映射表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.site_code_mapping (
    id              SERIAL          PRIMARY KEY,
    site_code       VARCHAR(10)     NOT NULL,
    site_id         BIGINT          NOT NULL,
    site_name       VARCHAR(100),
    tenant_id       INT,
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

-- site_code 唯一约束（格式：2字母+3数字，如 AB123）
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_site_code_mapping_site_code' AND conrelid = 'auth.site_code_mapping'::regclass
    ) THEN
        ALTER TABLE auth.site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_code UNIQUE (site_code);
    END IF;
END $$;

-- site_id 唯一约束
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_site_code_mapping_site_id' AND conrelid = 'auth.site_code_mapping'::regclass
    ) THEN
        ALTER TABLE auth.site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_id UNIQUE (site_id);
    END IF;
END $$;

-- 索引
CREATE INDEX IF NOT EXISTS ix_site_code_mapping_site_code ON auth.site_code_mapping (site_code);

-- ---------------------------------------------------------------------------
-- 3. roles — 角色定义表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.roles (
    id              SERIAL          PRIMARY KEY,
    code            VARCHAR(50)     NOT NULL,
    name            VARCHAR(100),
    description     TEXT,
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_roles_code' AND conrelid = 'auth.roles'::regclass
    ) THEN
        ALTER TABLE auth.roles ADD CONSTRAINT uq_roles_code UNIQUE (code);
    END IF;
END $$;

-- ---------------------------------------------------------------------------
-- 4. permissions — 权限定义表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.permissions (
    id              SERIAL          PRIMARY KEY,
    code            VARCHAR(50)     NOT NULL,
    name            VARCHAR(100),
    description     TEXT,
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_permissions_code' AND conrelid = 'auth.permissions'::regclass
    ) THEN
        ALTER TABLE auth.permissions ADD CONSTRAINT uq_permissions_code UNIQUE (code);
    END IF;
END $$;

-- ---------------------------------------------------------------------------
-- 5. role_permissions — 角色-权限关联表（联合主键）
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.role_permissions (
    role_id         INT             NOT NULL,
    permission_id   INT             NOT NULL,
    PRIMARY KEY (role_id, permission_id)
);

-- 外键（幂等添加）
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_role_permissions_role_id' AND conrelid = 'auth.role_permissions'::regclass
    ) THEN
        ALTER TABLE auth.role_permissions
            ADD CONSTRAINT fk_role_permissions_role_id
            FOREIGN KEY (role_id) REFERENCES auth.roles (id) ON DELETE CASCADE;
    END IF;

    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_role_permissions_permission_id' AND conrelid = 'auth.role_permissions'::regclass
    ) THEN
        ALTER TABLE auth.role_permissions
            ADD CONSTRAINT fk_role_permissions_permission_id
            FOREIGN KEY (permission_id) REFERENCES auth.permissions (id) ON DELETE CASCADE;
    END IF;
END $$;

-- ---------------------------------------------------------------------------
-- 6. user_applications — 用户入驻申请表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.user_applications (
    id                  SERIAL          PRIMARY KEY,
    user_id             INT             NOT NULL,
    site_code           VARCHAR(10)     NOT NULL,
    site_id             BIGINT,
    applied_role_text   VARCHAR(100)    NOT NULL,
    employee_number     VARCHAR(50),
    phone               VARCHAR(20)     NOT NULL,
    status              VARCHAR(20)     NOT NULL DEFAULT 'pending',
    reviewer_id         INT,
    review_note         TEXT,
    created_at          TIMESTAMPTZ     NOT NULL DEFAULT now(),
    reviewed_at         TIMESTAMPTZ
);

-- 外键
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_user_applications_user_id' AND conrelid = 'auth.user_applications'::regclass
    ) THEN
        ALTER TABLE auth.user_applications
            ADD CONSTRAINT fk_user_applications_user_id
            FOREIGN KEY (user_id) REFERENCES auth.users (id) ON DELETE CASCADE;
    END IF;
END $$;

-- 索引
CREATE INDEX IF NOT EXISTS ix_user_applications_user_id ON auth.user_applications (user_id);
CREATE INDEX IF NOT EXISTS ix_user_applications_status  ON auth.user_applications (status);

-- ---------------------------------------------------------------------------
-- 7. user_site_roles — 用户-门店-角色关联表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.user_site_roles (
    id              SERIAL          PRIMARY KEY,
    user_id         INT             NOT NULL,
    site_id         BIGINT          NOT NULL,
    role_id         INT             NOT NULL,
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

-- 外键
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_user_site_roles_user_id' AND conrelid = 'auth.user_site_roles'::regclass
    ) THEN
        ALTER TABLE auth.user_site_roles
            ADD CONSTRAINT fk_user_site_roles_user_id
            FOREIGN KEY (user_id) REFERENCES auth.users (id) ON DELETE CASCADE;
    END IF;

    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_user_site_roles_role_id' AND conrelid = 'auth.user_site_roles'::regclass
    ) THEN
        ALTER TABLE auth.user_site_roles
            ADD CONSTRAINT fk_user_site_roles_role_id
            FOREIGN KEY (role_id) REFERENCES auth.roles (id) ON DELETE CASCADE;
    END IF;
END $$;

-- 唯一约束：同一用户在同一门店下不能重复分配同一角色
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'uq_user_site_roles_user_site_role' AND conrelid = 'auth.user_site_roles'::regclass
    ) THEN
        ALTER TABLE auth.user_site_roles
            ADD CONSTRAINT uq_user_site_roles_user_site_role UNIQUE (user_id, site_id, role_id);
    END IF;
END $$;

-- 索引
CREATE INDEX IF NOT EXISTS ix_user_site_roles_user_site ON auth.user_site_roles (user_id, site_id);

-- ---------------------------------------------------------------------------
-- 8. user_assistant_binding — 用户-人员绑定表
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS auth.user_assistant_binding (
    id              SERIAL          PRIMARY KEY,
    user_id         INT             NOT NULL,
    site_id         BIGINT          NOT NULL,
    assistant_id    BIGINT,
    staff_id        BIGINT,
    binding_type    VARCHAR(20)     NOT NULL,
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT now()
);

-- 外键
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
        WHERE conname = 'fk_user_assistant_binding_user_id' AND conrelid = 'auth.user_assistant_binding'::regclass
    ) THEN
        ALTER TABLE auth.user_assistant_binding
            ADD CONSTRAINT fk_user_assistant_binding_user_id
            FOREIGN KEY (user_id) REFERENCES auth.users (id) ON DELETE CASCADE;
    END IF;
END $$;

-- ---------------------------------------------------------------------------
-- 授予 app_user 对新表的 SEQUENCE 使用权限（SERIAL 字段需要）
-- ---------------------------------------------------------------------------
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA auth TO app_user;

-- =============================================================================
-- 回滚脚本（按逆序执行）
-- =============================================================================
-- DROP TABLE IF EXISTS auth.user_assistant_binding CASCADE;
-- DROP TABLE IF EXISTS auth.user_site_roles CASCADE;
-- DROP TABLE IF EXISTS auth.user_applications CASCADE;
-- DROP TABLE IF EXISTS auth.role_permissions CASCADE;
-- DROP TABLE IF EXISTS auth.permissions CASCADE;
-- DROP TABLE IF EXISTS auth.roles CASCADE;
-- DROP TABLE IF EXISTS auth.site_code_mapping CASCADE;
-- DROP TABLE IF EXISTS auth.users CASCADE;
