/**
 * 관리자 API 클라이언트 (감사 로그, 접근 이력, 로그인 이력, 권한 트리, 역할).
 */

const API_BASE = import.meta.env.VITE_API_URL ?? '/api';

export interface PageResponse<T> {
  content: T[];
  totalElements: number;
  totalPages: number;
  number: number;
  size: number;
}

export interface AuditLog {
  auditSn: number;
  userId: string | null;
  userAcnt: string | null;
  actionCd: string;
  resourceType: string | null;
  resourceId: string | null;
  detail: Record<string, unknown> | null;
  ipAddress: string | null;
  result: string | null;
  failReason: string | null;
  createdAt: string;
}

export interface AccessLog {
  accessSn: number;
  userId: string | null;
  userAcnt: string | null;
  httpMethod: string;
  requestPath: string;
  queryString: string | null;
  statusCode: number;
  durationMs: number;
  ipAddress: string | null;
  userAgent: string | null;
  createdAt: string;
}

export interface LoginHistory {
  histSn: number;
  userId: string | null;
  userAcnt: string;
  loginDtm: string;
  loginIp: string | null;
  userAgent: string | null;
  result: string;
  failReason: string | null;
  authProvider: string | null;
}

export interface PermTreeNode {
  rsrcCd: string;
  parentCd: string | null;
  rsrcNm: string;
  rsrcDesc: string | null;
  icon: string | null;
  rsrcLevel: number;
  sortOrd: number;
  useYn: string;
  /** V021: 메뉴 SSOT */
  labelKey: string | null;
  urlPath: string | null;
  navSort: number;
  /** V022: DB i18n JSONB {"ko":"...", "en":"..."} */
  labels: Record<string, string>;
}

export interface RoleWithPermissions {
  roleSn: number;
  roleCd: string;
  roleNm: string;
  roleDc: string;
  /** UI 표기 색상 (#RRGGBB). NULL이면 프론트 기본 팔레트에서 결정 */
  colorHex: string | null;
  dfltYn: string;
  builtinYn: string;
  permissions: { permSn: number; roleSn: number; rsrcCd: string; operCd: string; grantYn: string }[];
}

async function apiGet<T>(path: string): Promise<T> {
  const res = await fetch(`${API_BASE}${path}`, { credentials: 'include' });
  if (!res.ok) throw new Error(`API ${res.status}: ${path}`);
  return res.json();
}

export function fetchAuditLogs(page = 0, size = 50) {
  return apiGet<PageResponse<AuditLog>>(`/admin/audit-logs?page=${page}&size=${size}`);
}

export function fetchAccessLogs(page = 0, size = 50) {
  return apiGet<PageResponse<AccessLog>>(`/admin/access-logs?page=${page}&size=${size}`);
}

export function fetchLoginHistory(page = 0, size = 50) {
  return apiGet<PageResponse<LoginHistory>>(`/admin/login-history?page=${page}&size=${size}`);
}

export function fetchPermTree() {
  return apiGet<PermTreeNode[]>('/perm-tree');
}

import { updateRoleColorCache } from '@shared/constants/userRoles';

export async function fetchRoles(): Promise<RoleWithPermissions[]> {
  const roles = await apiGet<RoleWithPermissions[]>('/roles');
  // 역할 색상 캐시 즉시 갱신 → 모든 사용처 자동 반영
  updateRoleColorCache(roles);
  return roles;
}

// ─── 역할 CRUD ───────────────────────────────
export interface RoleCreatePayload {
  roleCd: string;
  roleNm: string;
  roleDc?: string;
  colorHex?: string;
  dfltYn?: string;
}

export interface RoleUpdatePayload {
  roleNm?: string;
  roleDc?: string;
  colorHex?: string;
  dfltYn?: string;
}

async function apiSend<T>(method: string, path: string, body?: unknown): Promise<T> {
  const res = await fetch(`${API_BASE}${path}`, {
    method,
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!res.ok) {
    let msg = `API ${res.status}`;
    try { const b = await res.json(); if (b?.message) msg += `: ${b.message}`; } catch { /* */ }
    throw new Error(msg);
  }
  return res.json();
}

export function createRole(payload: RoleCreatePayload) {
  return apiSend<{ roleSn: number; roleCd: string; roleNm: string }>('POST', '/roles', payload);
}

export function updateRole(roleSn: number, payload: RoleUpdatePayload) {
  return apiSend('PUT', `/roles/${roleSn}`, payload);
}

export function deleteRole(roleSn: number) {
  return apiSend('DELETE', `/roles/${roleSn}`);
}

// ─── 권한 매트릭스 갱신 ────────────────────────
export interface PermEntry {
  rsrcCd: string;
  operCd: string;
  grantYn: 'Y' | 'N' | null;  // null = 명시 권한 제거 (상속 모드)
}

export function updateRolePermissions(roleSn: number, permissions: PermEntry[]) {
  return apiSend<{ ok: boolean; changed: number }>('PUT', `/roles/${roleSn}/permissions`, { permissions });
}

// ─── 사용자 역할 배정 ─────────────────────────
export function assignUserRoles(userId: string, roleSns: number[]) {
  return apiSend<{ userId: string; roles: string[] }>('PUT', `/admin/users/${userId}/roles`, { roleSns });
}

// ============================================================================
// 사용자 관리
// ============================================================================

export interface AdminUser {
  userId: string;
  userAcnt: string;
  userNm: string;
  rnkpNm: string | null;
  email: string | null;
  userSttsCd: string;
  authProvider: string;
  failCnt: number;
  lastLoginDtm: string | null;
  createdAt: string;
  roles: string[];
}

export interface UserStats {
  total: number;
  active: number;
  locked: number;
  inactive: number;
  pending: number;
  byStatus: Record<string, number>;
  byProvider: Record<string, number>;
  byRole: Record<string, number>;
}

export function fetchUsers() {
  return apiGet<AdminUser[]>('/admin/users');
}

export function fetchUserStats() {
  return apiGet<UserStats>('/admin/users/stats');
}

export async function unlockUser(userId: string) {
  const res = await fetch(`${API_BASE}/admin/users/${userId}/unlock`, {
    method: 'POST',
    credentials: 'include',
  });
  if (!res.ok) throw new Error(`API ${res.status}: unlock`);
  return res.json();
}

export async function changeUserStatus(userId: string, status: string) {
  const res = await fetch(`${API_BASE}/admin/users/${userId}/status`, {
    method: 'PUT',
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ status }),
  });
  if (!res.ok) throw new Error(`API ${res.status}: status`);
  return res.json();
}

// ============================================================================
// 통계 (대시보드 카드)
// ============================================================================

export interface AuditStats {
  total: number;
  last24h: number;
  failed24h: number;
  byAction: { action: string; count: number }[];
  hourly24: { hour: string; count: number }[];
}

export interface AccessStats {
  total: number;
  last24h: number;
  error4xx: number;
  error5xx: number;
  avgDurationMs: number;
  topPaths: { path: string; count: number; avg_ms: number }[];
}

export interface LoginStats {
  total: number;
  success24h: number;
  failed24h: number;
  locked24h: number;
  successRate: number;
  byUser: { user_acnt: string; count: number }[];
  daily7d: { day: string; success: number; failed: number; locked: number }[];
}

export function fetchAuditStats() {
  return apiGet<AuditStats>('/admin/stats/audit');
}

export function fetchAccessStats() {
  return apiGet<AccessStats>('/admin/stats/access');
}

export function fetchLoginStats() {
  return apiGet<LoginStats>('/admin/stats/login');
}
