/*
 * M18 관리자 모듈(SCR-A5·A6) 실배선 API 계약.
 * 공용 클라이언트(../../api/client)만 사용 — client.ts·endpoints.ts 무수정.
 * 정본: 백엔드 컨트롤러 시그니처
 *   - GET  /api/admin/audit   → ApiResponse<PageResponse<AuditLogDto>>  (AuditLogController)
 *   - GET  /api/admin/settings, GET /{key}, POST, DELETE /{key}          (SettingController)
 * ★ 감사로그 DTO에는 자격증명·IP 원문이 포함되지 않는다(백엔드가 ipHint=null·민감정보 제외로 기록).
 *   설정 DTO는 secretYn='Y' 값이 백엔드에서 마스킹(********)되어 도착한다.
 */
import { api } from '../../api/client';
import type { PageResponse } from '../../api/types';

// ── SCR-A5 감사로그 ──
/** 감사 로그 행(조회). 민감정보 미포함(계약 §0-3/§7-3). */
export interface AuditLogRow {
  id: number;
  actorId: string | null;
  actorName: string | null;
  action: string | null;
  targetType: string | null;
  targetId: string | null;
  eventId: string | null;
  summary: string | null;
  result: string | null;
  createdAt: string | null;
}

export interface AuditSearchParams {
  action?: string;
  actorId?: string;
  eventId?: string;
  page?: number;
  size?: number;
}

export const auditApi = {
  search: (p: AuditSearchParams = {}) => {
    const qs = new URLSearchParams();
    if (p.action) qs.set('action', p.action);
    if (p.actorId) qs.set('actorId', p.actorId);
    if (p.eventId) qs.set('eventId', p.eventId);
    qs.set('page', String(p.page ?? 0));
    qs.set('size', String(p.size ?? 20));
    return api.get<PageResponse<AuditLogRow>>(`/api/admin/audit?${qs.toString()}`);
  },
};

/** 백엔드 @Audited 액션 상수(datalist 힌트) — 필터 자동완성용. */
export const KNOWN_AUDIT_ACTIONS = [
  'LOGIN_SLIDE_CREATE',
  'LOGIN_SLIDE_UPDATE',
  'LOGIN_SLIDE_DELETE',
  'SETTING_SAVE',
  'SETTING_DELETE',
  'ROLE_SAVE',
  'ROLE_DELETE',
  'MENU_SAVE',
  'MENU_DELETE',
  'CODE_SAVE',
  'CODE_DELETE',
  'CODE_GROUP_SAVE',
  'CODE_GROUP_DELETE',
  'NOTICE_CREATE',
  'NOTICE_UPDATE',
  'NOTICE_DELETE',
  'OPINION_COMMENT',
  'OPINION_STATUS',
  'SYS_USER_CREATE',
  'SYS_USER_UPDATE',
  'SYS_USER_STATUS',
  'SYS_USER_PW_RESET',
  'SYS_USER_OTP_RESET',
] as const;

// ── SCR-A6 시스템설정 ──
/** 시스템 설정 항목. secretYn='Y' 이면 settingValue 는 마스킹(********)되어 전달된다(원문 미노출). */
export interface SettingRow {
  settingKey: string;
  settingValue: string | null;
  valueType: string | null;
  description: string | null;
  secretYn: string | null;
}

export interface SettingSaveBody {
  settingKey: string;
  settingValue?: string | null;
  valueType?: string | null;
  description?: string | null;
  secretYn?: string | null;
}

/** 백엔드 마스킹 값(SettingService.MASK) — 마스킹된 시크릿은 미변경 시 저장 전송 제외. */
export const SETTING_MASK = '********';

export const settingApi = {
  list: () => api.get<SettingRow[]>('/api/admin/settings'),
  save: (body: SettingSaveBody) => api.post<void>('/api/admin/settings', body),
  remove: (key: string) => api.del<void>(`/api/admin/settings/${encodeURIComponent(key)}`),
};

// ── SCR-A8 규정 룰셋 버전 조회(읽기 전용) ──
/**
 * 룰셋 파일 요약. 백엔드 GET /api/admin/rulesets (AdminRulesetController) 계약.
 * 룰셋은 classpath 리소스로 버전 관리되며 편집 API는 없다(규정 개정 = 리소스 교체).
 */
export interface RulesetSummary {
  name: string; // 파일명 (예: compliance-v1.json)
  version: string;
  effectiveDate: string | null;
  ruleCount: number;
  moduleDistribution: Record<string, number>;
}

/** 규정 룰셋 규칙 1건(compliance-*.json rules[] 항목). 요율 마스터에는 rules 가 없다. */
export interface RulesetRule {
  code: string;
  group?: string | null;
  label?: string | null;
  module?: string[] | null;
  severity?: 'block' | 'warn' | string | null;
  metric?: string | null;
  operator?: string | null;
  threshold?: number | null;
  min?: number | null;
  max?: number | null;
  unit?: string | null;
  requiresDocument?: string | null;
  hallLimits?: Record<string, number> | null;
  forbidden?: string[] | null;
  note?: string | null;
}

/** 룰셋 규칙 전문(JSON 원문). 규정 파일은 rules[], 요율 파일은 rental/utility 등. */
export interface RulesetDetail {
  rulesetVersion?: string | null;
  effectiveDate?: string | null;
  disclaimer?: string | null;
  source?: string | null;
  rules?: RulesetRule[] | null;
}

export const rulesetApi = {
  list: () => api.get<RulesetSummary[]>('/api/admin/rulesets'),
  detail: (name: string) =>
    api.get<RulesetDetail>(`/api/admin/rulesets/${encodeURIComponent(name)}`),
};
