/**
 * Amaranth (Wehago/RPS ERP) REST API 연결 프리셋 자동 시드.
 *
 * 백엔드 부팅 시 1회 호출되어, 외부 REST API 연결 목록에 5개 마스터 동기화 엔드포인트가
 * 없으면 자동으로 등록합니다. 이미 존재하는 연결명은 건너뜁니다.
 *
 * 호출: app.ts 부팅 직후 (DB 풀 초기화 후)
 */
import { getPool } from "../database/db";
import { ExternalRestApiConnectionService } from "./externalRestApiConnectionService";
import { logger } from "../utils/logger";

const DEFAULT_COMPANY_CODE = process.env.DEFAULT_COMPANY_CODE || "COMPANY_16";

const AUTH_CONFIG = {
  callerName: "API_gcmsAmaranth40578",
  accessToken: "MN5KzKBWRAa92BPxDlRLl3GcsxeZXc",
  hashKey: "22519103205540290721741689643674301018832465",
  groupSeq: "gcmsAmaranth40578",
};

const COMMON_HEADERS = {
  "Content-Type": "application/json; charset=UTF-8",
  Accept: "application/json",
};

const PRESETS = [
  {
    connection_name: "Amaranth - 부서",
    description: "Wehago/Amaranth api16S10 — 부서 마스터 (dept_info)",
    endpoint_path: "/apiproxy/api16S10",
    default_body: JSON.stringify({ coCd: "1000" }, null, 2),
  },
  {
    connection_name: "Amaranth - 사원",
    description: "Wehago/Amaranth api16S05 — 사원 마스터 (user_info, sabun 기반 UPSERT)",
    endpoint_path: "/apiproxy/api16S05",
    default_body: JSON.stringify(
      {
        header: { groupSeq: AUTH_CONFIG.groupSeq, empSeq: "", tId: "", pId: "" },
        body: { coCd: "1000", extraColumns: ["emalAdd", "outemalAdd", "emgcTel", "tel", "joinDt"] },
      },
      null,
      2
    ),
  },
  {
    connection_name: "Amaranth - Wehago 사용자",
    description: "Wehago/Amaranth api99u01A11 — Wehago 사용자(loginId) 조회. 사원 동기화 후 emp_seq 기준으로 user_id 채움.",
    endpoint_path: "/apiproxy/api99u01A11",
    default_body: JSON.stringify(
      {
        header: { groupSeq: AUTH_CONFIG.groupSeq, tId: "", pId: "" },
        body: { langCode: "kr" }, // 전체 조회 (arrEmpSeq 없으면 전체)
      },
      null,
      2
    ),
  },
  {
    connection_name: "Amaranth - 거래처",
    description: "Wehago/Amaranth api16S11 — 거래처 마스터 (customer_mng)",
    endpoint_path: "/apiproxy/api16S11",
    default_body: JSON.stringify({ coCd: "1000" }, null, 2),
  },
  {
    connection_name: "Amaranth - 창고",
    description: "Wehago/Amaranth api20A00S00801 — 창고/위치 마스터 (warehouse_info)",
    endpoint_path: "/apiproxy/api20A00S00801",
    default_body: JSON.stringify({ coCd: "1000", baselocFg: "0" }, null, 2),
  },
  {
    connection_name: "Amaranth - 계정과목",
    description: "Wehago/Amaranth api11A02 — 계정과목 마스터 (account_code_info)",
    endpoint_path: "/apiproxy/api11A02",
    default_body: JSON.stringify({ coCd: "1000" }, null, 2),
  },
  {
    // 전자결재 통합 연결 — base_url + 인증정보만 사용. 실제 endpoint(api99u01A01/02A01/02A02/02A04/03A03 등)는 호출자가 지정
    connection_name: "Amaranth - 결재",
    description:
      "Wehago/Amaranth 전자결재 통합 — 인증토큰(api99u01A01) / 결재함(api99u02A01) / 문서목록(api99u02A02) / 문서상세(api99u02A04) / SSO(authUser/api99u01A02) / 상신(authUser/api99u03A03). " +
      "endpoint_path 는 비워두고, 결재 클라이언트가 동작별로 path 를 지정해 호출.",
    endpoint_path: "",
    default_body: JSON.stringify(
      { header: { groupSeq: AUTH_CONFIG.groupSeq }, body: {} },
      null,
      2
    ),
    extra_auth_config: {
      // SSO 암호화 키 (API상품연동설정에서 확인) — empSeq AES 암호화에 사용
      aesKey: "8441e27489d402cd",
    },
  },
];

export async function seedAmaranthPresets(): Promise<void> {
  const pool = getPool();

  // PK 시퀀스 보정 (이전 INSERT/마이그레이션으로 어긋났을 수 있음)
  try {
    await pool.query(
      `SELECT setval(pg_get_serial_sequence('external_rest_api_connections', 'id'),
                     COALESCE((SELECT MAX(id) FROM external_rest_api_connections), 1),
                     true)`
    );
  } catch (e: any) {
    logger.warn(`[seed] external_rest_api_connections 시퀀스 보정 실패 (무시): ${e?.message}`);
  }

  let created = 0;
  let updated = 0;
  let skipped = 0;

  for (const preset of PRESETS) {
    try {
      const existing = await pool.query<{ id: number; default_body: string | null; auth_config: any }>(
        "SELECT id, default_request_body AS default_body, auth_config FROM external_rest_api_connections WHERE connection_name = $1 LIMIT 1",
        [preset.connection_name]
      );

      if ((existing.rowCount ?? 0) > 0) {
        const row = existing.rows[0];

        // 1) default_body 가 비어있거나 빈 coCd 면 프리셋으로 갱신 (회사코드 1000 반영)
        const needsBodyUpdate =
          !row.default_body ||
          /"coCd"\s*:\s*""/.test(row.default_body) ||
          /"coCd"\s*:\s*null/.test(row.default_body);

        // 2) extra_auth_config 가 정의된 프리셋 (예: '결재' aesKey) 인데 기존 auth_config 에 누락된 경우 보강
        const extras = (preset as any).extra_auth_config;
        let needsAuthUpdate = false;
        let mergedAuth: any = null;
        if (extras) {
          const cfg = typeof row.auth_config === "string" ? JSON.parse(row.auth_config) : row.auth_config || {};
          for (const k of Object.keys(extras)) {
            if (!cfg[k]) {
              needsAuthUpdate = true;
              break;
            }
          }
          if (needsAuthUpdate) {
            mergedAuth = { ...cfg, ...extras };
          }
        }

        if (needsBodyUpdate || needsAuthUpdate) {
          await pool.query(
            `UPDATE external_rest_api_connections
             SET default_request_body = COALESCE($1, default_request_body),
                 auth_config          = COALESCE($2::jsonb, auth_config),
                 updated_date         = NOW(),
                 updated_by           = 'system-seed'
             WHERE id = $3`,
            [
              needsBodyUpdate ? preset.default_body : null,
              needsAuthUpdate ? JSON.stringify(mergedAuth) : null,
              row.id,
            ]
          );
          updated++;
        } else {
          skipped++;
        }
        continue;
      }

      const result = await ExternalRestApiConnectionService.createConnection({
        connection_name: preset.connection_name,
        description: preset.description,
        base_url: "https://erp.rps-korea.com",
        endpoint_path: preset.endpoint_path,
        default_headers: COMMON_HEADERS,
        default_method: "POST",
        default_body: preset.default_body,
        auth_type: "wehago",
        // 결재 같은 일부 프리셋은 AES 키 등 추가 설정이 필요하므로 extra_auth_config 를 합침
        auth_config: { ...AUTH_CONFIG, ...((preset as any).extra_auth_config || {}) },
        timeout: 30000,
        retry_count: 0,
        retry_delay: 1000,
        company_code: DEFAULT_COMPANY_CODE,
        is_active: "Y",
        created_by: "system-seed",
      } as any);

      if (result.success) {
        created++;
      }
    } catch (e: any) {
      logger.warn(`[seed] Amaranth 프리셋 등록 실패 (${preset.connection_name}): ${e?.message}`);
    }
  }

  if (created > 0 || updated > 0 || skipped > 0) {
    logger.info(
      `🌱 Amaranth 프리셋 시드 완료: 신규 ${created}개 / 갱신 ${updated}개 / 동일 ${skipped}개 (회사: ${DEFAULT_COMPANY_CODE})`
    );
  }
}
