-- V19: 엑셀 업로드 매핑 템플릿 시스템

-- 1. upload_template (마스터)
CREATE TABLE upload_template (
    template_id     BIGSERIAL    PRIMARY KEY,
    template_code   VARCHAR(50)  NOT NULL UNIQUE,
    template_name   VARCHAR(100) NOT NULL,
    category        VARCHAR(30)  NOT NULL,           -- RECRUIT/MAINTAIN/CONTRACT/AGENT/CUSTOM
    target_table    VARCHAR(50)  NOT NULL,
    company_code    VARCHAR(20),                     -- NULL이면 범용
    header_row      INT          NOT NULL DEFAULT 1,
    data_start_row  INT          NOT NULL DEFAULT 2,
    sheet_index     INT          NOT NULL DEFAULT 0,
    sheet_name      VARCHAR(50),
    file_encoding   VARCHAR(20)  DEFAULT 'UTF-8',
    delimiter       VARCHAR(5),
    skip_empty_row  CHAR(1)      DEFAULT 'Y',
    max_error_count INT          DEFAULT 1000,
    batch_size      INT          DEFAULT 1000,
    description     VARCHAR(200),
    is_active       CHAR(1)      DEFAULT 'Y',
    created_at      TIMESTAMP    DEFAULT NOW(),
    created_by      BIGINT,
    updated_at      TIMESTAMP,
    updated_by      BIGINT
);

CREATE INDEX idx_upload_tpl_category ON upload_template(category);
CREATE INDEX idx_upload_tpl_company  ON upload_template(company_code) WHERE company_code IS NOT NULL;

-- 2. upload_template_column (컬럼 매핑 규칙)
CREATE TABLE upload_template_column (
    column_id          BIGSERIAL    PRIMARY KEY,
    template_id        BIGINT       NOT NULL REFERENCES upload_template(template_id) ON DELETE CASCADE,
    sort_order         INT          NOT NULL,
    source_type        VARCHAR(10)  NOT NULL DEFAULT 'COLUMN',  -- COLUMN/FIXED/EXPRESSION
    source_column      VARCHAR(10),                             -- 엑셀 컬럼 (A,B,C 또는 0,1,2)
    source_header      VARCHAR(100),
    target_field       VARCHAR(50)  NOT NULL,
    target_type        VARCHAR(20)  NOT NULL DEFAULT 'STRING',  -- STRING/NUMBER/DECIMAL/DATE/INTEGER
    transform_rule     VARCHAR(30),                             -- TRIM/UPPER/LOWER/DATE/DIVIDE/MULTIPLY/LOOKUP/CODE_MAP/FIXED/REPLACE/SUBSTRING/CONCAT/DEFAULT/REQUIRED
    transform_param    VARCHAR(200),                            -- JSON 또는 단순값
    date_format        VARCHAR(30),
    number_divide      INT,
    number_multiply    INT,
    fixed_value        VARCHAR(200),
    default_value      VARCHAR(200),
    lookup_table       VARCHAR(50),
    lookup_source_field VARCHAR(50),
    lookup_target_field VARCHAR(50),
    code_map_group     VARCHAR(50),
    is_required        CHAR(1)      DEFAULT 'N',
    validation_regex   VARCHAR(200),
    validation_message VARCHAR(200),
    description        VARCHAR(200),
    UNIQUE (template_id, sort_order)
);

CREATE INDEX idx_upload_tpl_col ON upload_template_column(template_id);

-- 3. upload_history (업로드 이력)
CREATE TABLE upload_history (
    history_id      BIGSERIAL    PRIMARY KEY,
    template_id     BIGINT       NOT NULL REFERENCES upload_template(template_id),
    template_code   VARCHAR(50)  NOT NULL,
    file_name       VARCHAR(300) NOT NULL,
    file_size       BIGINT,
    total_count     INT          NOT NULL DEFAULT 0,
    success_count   INT          NOT NULL DEFAULT 0,
    error_count     INT          NOT NULL DEFAULT 0,
    skip_count      INT          NOT NULL DEFAULT 0,
    error_file_id   BIGINT,                          -- file_storage 느슨한 참조 (제약 없음)
    status          VARCHAR(10)  NOT NULL DEFAULT 'PROCESSING',  -- PROCESSING/COMPLETED/FAILED/CANCELLED
    error_message   TEXT,
    started_at      TIMESTAMP    NOT NULL DEFAULT NOW(),
    finished_at     TIMESTAMP,
    duration_sec    INT,
    created_by      BIGINT
);

CREATE INDEX idx_upload_history_tpl     ON upload_history(template_id, started_at DESC);
CREATE INDEX idx_upload_history_started ON upload_history(started_at DESC);

-- 4. 메뉴 등록 (GRP_SYSTEM 하위, sort_order 7)
INSERT INTO menu (menu_code, menu_name, menu_type, menu_path, component_path, menu_icon,
                  menu_level, sort_order, is_visible, is_active, parent_menu_id, description)
VALUES ('SYSTEM_UPLOAD_TEMPLATE', '엑셀 업로드 템플릿', 'PAGE', '/system/upload-templates',
        'system/UploadTemplateManager', 'file-spreadsheet', 2, 7, 'Y', 'Y',
        (SELECT menu_id FROM menu WHERE menu_code = 'GRP_SYSTEM'),
        '보험사별 엑셀 업로드 양식 매핑 관리')
ON CONFLICT (menu_code) DO NOTHING;

-- 5. 메뉴 권한 4건 정의
INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order)
SELECT menu_id, 'READ',   '조회', 1 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (menu_id, perm_code) DO NOTHING;

INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order)
SELECT menu_id, 'CREATE', '등록', 2 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (menu_id, perm_code) DO NOTHING;

INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order)
SELECT menu_id, 'UPDATE', '수정', 3 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (menu_id, perm_code) DO NOTHING;

INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order)
SELECT menu_id, 'DELETE', '삭제', 4 FROM menu WHERE menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (menu_id, perm_code) DO NOTHING;

-- 6. SUPER_ADMIN / ADMIN : READ + CREATE + UPDATE + DELETE
INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted)
SELECT r.role_id, m.menu_id, p.perm_code, 'Y'
  FROM role r
  CROSS JOIN menu m
  CROSS JOIN (VALUES ('READ'), ('CREATE'), ('UPDATE'), ('DELETE')) AS p(perm_code)
 WHERE r.role_code IN ('SUPER_ADMIN', 'ADMIN')
   AND m.menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (role_id, menu_id, perm_code) DO NOTHING;

-- 7. MANAGER : READ 만
INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted)
SELECT r.role_id, m.menu_id, 'READ', 'Y'
  FROM role r
  CROSS JOIN menu m
 WHERE r.role_code = 'MANAGER'
   AND m.menu_code = 'SYSTEM_UPLOAD_TEMPLATE'
ON CONFLICT (role_id, menu_id, perm_code) DO NOTHING;
