-- =============================================
-- 文件管理系统 - Oracle 初始化脚本
-- 注意: 需要 Oracle 12c+ (IDENTITY 支持)
-- =============================================

-- ========== 用户与权限 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_user (
        id            NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        username      VARCHAR2(64) UNIQUE NOT NULL,
        password      VARCHAR2(256) NOT NULL,
        email         VARCHAR2(128),
        nickname      VARCHAR2(64),
        avatar        VARCHAR2(512),
        role          VARCHAR2(32) DEFAULT ''user'',
        dept_id       NUMBER DEFAULT 0,
        status        NUMBER(3) DEFAULT 1,
        storage_quota NUMBER DEFAULT 10737418240,
        used_storage  NUMBER DEFAULT 0,
        must_change_pwd NUMBER(3) DEFAULT 0,
        created_at    TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at    TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_role (
        id           NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name         VARCHAR2(64) UNIQUE NOT NULL,
        display_name VARCHAR2(64) NOT NULL,
        description  VARCHAR2(256),
        is_system    NUMBER(3) DEFAULT 0,
        status       NUMBER(3) DEFAULT 1,
        created_at   TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at   TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_permission (
        id          NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        code        VARCHAR2(64) UNIQUE NOT NULL,
        name        VARCHAR2(64) NOT NULL,
        resource    VARCHAR2(32) NOT NULL,
        action      VARCHAR2(32) NOT NULL,
        description VARCHAR2(256)
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_role_permission (
        role_id       NUMBER NOT NULL,
        permission_id NUMBER NOT NULL,
        PRIMARY KEY (role_id, permission_id)
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_user_role (
        user_id NUMBER NOT NULL,
        role_id NUMBER NOT NULL,
        PRIMARY KEY (user_id, role_id)
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== SSO ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_provider (
        id           NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name         VARCHAR2(64) NOT NULL,
        type         VARCHAR2(32) NOT NULL,
        display_name VARCHAR2(64) NOT NULL,
        icon         VARCHAR2(512),
        config       CLOB,
        auto_create  NUMBER(3) DEFAULT 1,
        default_role VARCHAR2(32) DEFAULT ''user'',
        status       NUMBER(3) DEFAULT 1,
        sort_order   NUMBER DEFAULT 0,
        created_at   TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at   TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_sso_session (
        id            NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        user_id       NUMBER NOT NULL,
        provider_id   NUMBER NOT NULL,
        external_id   VARCHAR2(256) NOT NULL,
        access_token  VARCHAR2(1024),
        refresh_token VARCHAR2(1024),
        expires_at    TIMESTAMP,
        last_login_at TIMESTAMP,
        created_at    TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_user ON fs_sso_session(user_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_sso_provider_ext ON fs_sso_session(provider_id, external_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 组织架构 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_department (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name       VARCHAR2(128) NOT NULL,
        code       VARCHAR2(64),
        parent_id  NUMBER DEFAULT 0,
        sort_order NUMBER DEFAULT 0,
        status     NUMBER(3) DEFAULT 1,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 文件管理 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_folder (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        biz_id     VARCHAR2(128) DEFAULT '''',
        name       VARCHAR2(256) NOT NULL,
        parent_id  NUMBER DEFAULT 0,
        owner_id   NUMBER NOT NULL,
        path       VARCHAR2(1024) NOT NULL,
        status     NUMBER(3) DEFAULT 1,
        version    NUMBER DEFAULT 1,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_parent ON fs_folder(parent_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_owner ON fs_folder(owner_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_folder_biz ON fs_folder(biz_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_file (
        id               NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name             VARCHAR2(256) NOT NULL,
        extension        VARCHAR2(32),
        folder_id        NUMBER NOT NULL,
        owner_id         NUMBER NOT NULL,
        size             NUMBER DEFAULT 0,
        md5              VARCHAR2(32),
        sha256           VARCHAR2(64),
        storage_key      VARCHAR2(512) NOT NULL,
        storage_policy_id NUMBER DEFAULT 1,
        mime_type        VARCHAR2(128),
        is_favorite      NUMBER(3) DEFAULT 0,
        status           NUMBER(3) DEFAULT 1,
        download_count   NUMBER DEFAULT 0,
        version          NUMBER DEFAULT 1,
        created_at       TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at       TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_file_folder ON fs_file(folder_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_file_owner ON fs_file(owner_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_file_md5 ON fs_file(md5)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_file_permission (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        file_id    NUMBER NOT NULL,
        user_id    NUMBER DEFAULT 0,
        role_id    NUMBER DEFAULT 0,
        perm_level VARCHAR2(16) DEFAULT ''read'',
        grant_by   NUMBER NOT NULL,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_user_file ON fs_file_permission(user_id, file_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_fp_role_file ON fs_file_permission(role_id, file_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_share (
        id             NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        file_id        NUMBER NOT NULL,
        owner_id       NUMBER NOT NULL,
        share_code     VARCHAR2(32) UNIQUE NOT NULL,
        password       VARCHAR2(64),
        expire_at      TIMESTAMP,
        max_download   NUMBER DEFAULT 0,
        download_count NUMBER DEFAULT 0,
        allow_preview  NUMBER(3) DEFAULT 1,
        allow_download NUMBER(3) DEFAULT 1,
        status         NUMBER(3) DEFAULT 1,
        created_at     TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 存储策略 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_policy (
        id          NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name        VARCHAR2(64) NOT NULL,
        type        VARCHAR2(32) NOT NULL,
        policy_type VARCHAR2(32) DEFAULT '''',
        config      CLOB,
        status      NUMBER(3) DEFAULT 1,
        created_at  TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_storage_assignment (
        id            NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        policy_id     NUMBER NOT NULL,
        user_id       NUMBER DEFAULT 0,
        group_id      NUMBER DEFAULT 0,
        is_default    NUMBER(3) DEFAULT 0,
        priority      NUMBER DEFAULT 0,
        storage_quota NUMBER DEFAULT 0,
        access_mode   VARCHAR2(32),
        status        NUMBER(3) DEFAULT 1,
        created_at    TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at    TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_policy ON fs_storage_assignment(policy_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_user ON fs_storage_assignment(user_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_assign_group ON fs_storage_assignment(group_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 开放平台 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_app (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        app_id     VARCHAR2(64) UNIQUE NOT NULL,
        app_secret VARCHAR2(128) NOT NULL,
        app_name   VARCHAR2(128) NOT NULL,
        status     NUMBER(3) DEFAULT 1,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_app_user (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        app_id     NUMBER NOT NULL,
        user_id    NUMBER NOT NULL,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 分片上传 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_upload_session (
        id           VARCHAR2(64) PRIMARY KEY,
        file_name    VARCHAR2(256) NOT NULL,
        file_size    NUMBER NOT NULL,
        chunk_size   NUMBER NOT NULL,
        total_chunks NUMBER NOT NULL,
        uploaded     NUMBER DEFAULT 0,
        md5          VARCHAR2(64),
        sha256       VARCHAR2(64),
        folder_id    NUMBER DEFAULT 0,
        owner_id     NUMBER NOT NULL,
        policy_id    NUMBER DEFAULT 0,
        file_id      NUMBER DEFAULT 0,
        status       NUMBER(3) DEFAULT 1,
        temp_dir     VARCHAR2(512),
        created_at   TIMESTAMP DEFAULT SYSTIMESTAMP,
        updated_at   TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 操作日志 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_operation_log (
        id          NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        user_id     NUMBER NOT NULL,
        username    VARCHAR2(64),
        action      VARCHAR2(32) NOT NULL,
        resource    VARCHAR2(32) NOT NULL,
        target_id   NUMBER DEFAULT 0,
        target_name VARCHAR2(256),
        detail      CLOB,
        ip          VARCHAR2(64),
        created_at  TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_log_user ON fs_operation_log(user_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_log_created ON fs_operation_log(created_at)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

-- ========== 备份 ==========

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_policy (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        name       VARCHAR2(128) NOT NULL,
        type       VARCHAR2(32) NOT NULL,
        config     CLOB,
        status     NUMBER(3) DEFAULT 1,
        last_run   TIMESTAMP,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE fs_backup_log (
        id         NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        policy_id  NUMBER NOT NULL,
        status     NUMBER(3) DEFAULT 1,
        file_path  VARCHAR2(512),
        file_size  NUMBER DEFAULT 0,
        detail     CLOB,
        created_at TIMESTAMP DEFAULT SYSTIMESTAMP
    )';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/

BEGIN
    EXECUTE IMMEDIATE 'CREATE INDEX idx_backup_policy ON fs_backup_log(policy_id)';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -955 THEN RAISE; END IF;
END;
/
