/**
 * 화면 그룹 관리 API 클라이언트
 * - 화면 그룹 (screen_groups)
 * - 화면-그룹 연결 (screen_group_screens)
 * - 필드 조인 (screen_field_joins)
 * - 데이터 흐름 (screen_data_flows)
 * - 화면-테이블 관계 (screen_table_relations)
 */

import { apiClient } from "./client";

// ============================================================
// 타입 정의
// ============================================================

export interface ScreenGroup {
  id: number;
  group_name: string;
  group_code: string;
  main_table_name?: string;
  description?: string;
  icon?: string;
  display_order: number;
  is_active: string;
  company_code: string;
  created_date?: string;
  updated_date?: string;
  writer?: string;
  screen_count?: number;
  screens?: ScreenGroupScreen[];
  parent_group_id?: number | null;  // 상위 그룹 ID
  group_level?: number;             // 그룹 레벨 (0: 대분류, 1: 중분류, 2: 소분류 ...)
  hierarchy_path?: string;          // 계층 경로
}

export interface ScreenGroupScreen {
  id: number;
  group_id: number;
  screen_id: number;
  screen_name?: string;
  screen_role: string;
  display_order: number;
  is_default: string;
  company_code: string;
}

export interface FieldJoin {
  id: number;
  screen_id: number;
  layout_id?: number;
  component_id?: string;
  field_name?: string;
  save_table: string;
  save_column: string;
  join_table: string;
  join_column: string;
  display_column: string;
  join_type: string;
  filter_condition?: string;
  sort_column?: string;
  sort_direction?: string;
  is_active: string;
  save_table_label?: string;
  join_table_label?: string;
}

export interface DataFlow {
  id: number;
  group_id?: number;
  source_screen_id: number;
  source_action?: string;
  target_screen_id: number;
  target_action?: string;
  data_mapping?: Record<string, any>;
  flow_type: string;
  flow_label?: string;
  condition_expression?: string;
  is_active: string;
  source_screen_name?: string;
  target_screen_name?: string;
  group_name?: string;
}

export interface TableRelation {
  id: number;
  group_id?: number;
  screen_id: number;
  table_name: string;
  relation_type: string;
  crud_operations: string;
  description?: string;
  is_active: string;
  screen_name?: string;
  group_name?: string;
  table_label?: string;
}

export interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
  error?: string;
  total?: number;
  page?: number;
  size?: number;
  totalPages?: number;
}


// ============================================================
// 화면 그룹 (screen_groups) API
// ============================================================

export async function getScreenGroups(params?: {
  page?: number;
  size?: number;
  searchTerm?: string;
  excludePop?: boolean;
}): Promise<ApiResponse<ScreenGroup[]>> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.page) queryParams.append("page", params.page.toString());
    if (params?.size) queryParams.append("size", params.size.toString());
    if (params?.searchTerm) queryParams.append("searchTerm", params.searchTerm);
    if (params?.excludePop) queryParams.append("excludePop", "true");

    const response = await apiClient.get(`/screen-groups/groups?${queryParams.toString()}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function getScreenGroup(id: number): Promise<ApiResponse<ScreenGroup>> {
  try {
    const response = await apiClient.get(`/screen-groups/groups/${id}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function createScreenGroup(data: Partial<ScreenGroup>): Promise<ApiResponse<ScreenGroup>> {
  try {
    const response = await apiClient.post("/screen-groups/groups", data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function updateScreenGroup(id: number, data: Partial<ScreenGroup>): Promise<ApiResponse<ScreenGroup>> {
  try {
    const response = await apiClient.put(`/screen-groups/groups/${id}`, data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function deleteScreenGroup(id: number, options?: { deleteNumberingRules?: boolean }): Promise<ApiResponse<void>> {
  try {
    const params = new URLSearchParams();
    if (options?.deleteNumberingRules) {
      params.set("deleteNumberingRules", "true");
    }
    const queryString = params.toString();
    const url = `/screen-groups/groups/${id}${queryString ? `?${queryString}` : ""}`;
    const response = await apiClient.delete(url);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 화면-그룹 연결 (screen_group_screens) API
// ============================================================

export async function addScreenToGroup(data: {
  group_id: number;
  screen_id: number;
  screen_role?: string;
  display_order?: number;
  is_default?: string;
  target_company_code?: string; // 최고 관리자가 다른 회사로 복제할 때 사용
}): Promise<ApiResponse<ScreenGroupScreen>> {
  try {
    const response = await apiClient.post("/screen-groups/group-screens", data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function updateScreenInGroup(id: number, data: {
  screen_role?: string;
  display_order?: number;
  is_default?: string;
}): Promise<ApiResponse<ScreenGroupScreen>> {
  try {
    const response = await apiClient.put(`/screen-groups/group-screens/${id}`, data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function removeScreenFromGroup(id: number): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/screen-groups/group-screens/${id}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 필드 조인 (screen_field_joins) API
// ============================================================

export async function getFieldJoins(screenId?: number): Promise<ApiResponse<FieldJoin[]>> {
  try {
    const queryParams = screenId ? `?screen_id=${screenId}` : "";
    const response = await apiClient.get(`/screen-groups/field-joins${queryParams}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function createFieldJoin(data: Partial<FieldJoin>): Promise<ApiResponse<FieldJoin>> {
  try {
    const response = await apiClient.post("/screen-groups/field-joins", data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function updateFieldJoin(id: number, data: Partial<FieldJoin>): Promise<ApiResponse<FieldJoin>> {
  try {
    const response = await apiClient.put(`/screen-groups/field-joins/${id}`, data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function deleteFieldJoin(id: number): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/screen-groups/field-joins/${id}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 데이터 흐름 (screen_data_flows) API
// ============================================================

export async function getDataFlows(params?: { groupId?: number; sourceScreenId?: number }): Promise<ApiResponse<DataFlow[]>> {
  try {
    const queryParts: string[] = [];
    if (params?.groupId) {
      queryParts.push(`group_id=${params.groupId}`);
    }
    if (params?.sourceScreenId) {
      queryParts.push(`source_screen_id=${params.sourceScreenId}`);
    }
    const queryString = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
    const response = await apiClient.get(`/screen-groups/data-flows${queryString}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function createDataFlow(data: Partial<DataFlow>): Promise<ApiResponse<DataFlow>> {
  try {
    const response = await apiClient.post("/screen-groups/data-flows", data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function updateDataFlow(id: number, data: Partial<DataFlow>): Promise<ApiResponse<DataFlow>> {
  try {
    const response = await apiClient.put(`/screen-groups/data-flows/${id}`, data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function deleteDataFlow(id: number): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/screen-groups/data-flows/${id}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 화면-테이블 관계 (screen_table_relations) API
// ============================================================

export async function getTableRelations(params?: {
  screen_id?: number;
  group_id?: number;
}): Promise<ApiResponse<TableRelation[]>> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.screen_id) queryParams.append("screen_id", params.screen_id.toString());
    if (params?.group_id) queryParams.append("group_id", params.group_id.toString());

    const response = await apiClient.get(`/screen-groups/table-relations?${queryParams.toString()}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function createTableRelation(data: Partial<TableRelation>): Promise<ApiResponse<TableRelation>> {
  try {
    const response = await apiClient.post("/screen-groups/table-relations", data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function updateTableRelation(id: number, data: Partial<TableRelation>): Promise<ApiResponse<TableRelation>> {
  try {
    const response = await apiClient.put(`/screen-groups/table-relations/${id}`, data);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

export async function deleteTableRelation(id: number): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/screen-groups/table-relations/${id}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 화면 레이아웃 요약 (미리보기용) API
// ============================================================

// 레이아웃 아이템 (미니어처 렌더링용)
export interface LayoutItem {
  x: number;
  y: number;
  width: number;
  height: number;
  componentKind: string; // 정확한 컴포넌트 종류 (table-list, button-primary 등)
  widgetType: string; // 일반적인 위젯 타입 (button, text 등)
  label?: string;
  bindField?: string; // 바인딩된 필드명 (컬럼명)
  usedColumns?: string[]; // 이 컴포넌트에서 사용하는 컬럼 목록
  joinColumns?: string[]; // 이 컴포넌트에서 조인 컬럼 목록 (isEntityJoin=true)
}

export interface ScreenLayoutSummary {
  screenId: number;
  screenType: 'form' | 'grid' | 'dashboard' | 'action';
  widgetCounts: Record<string, number>;
  totalComponents: number;
  // 미니어처 렌더링용 레이아웃 데이터
  layoutItems: LayoutItem[];
  canvasWidth: number;
  canvasHeight: number;
}

// 단일 화면 레이아웃 요약 조회
export async function getScreenLayoutSummary(screenId: number): Promise<ApiResponse<ScreenLayoutSummary>> {
  try {
    const response = await apiClient.get(`/screen-groups/layout-summary/${screenId}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// 여러 화면 레이아웃 요약 일괄 조회
export async function getMultipleScreenLayoutSummary(
  screenIds: number[]
): Promise<ApiResponse<Record<number, ScreenLayoutSummary>>> {
  try {
    const response = await apiClient.post("/screen-groups/layout-summary/batch", { screenIds });
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// 필드 매핑 정보 타입
export interface FieldMappingInfo {
  sourceTable?: string;        // 연관 테이블명 (parentDataMapping에서 사용)
  sourceField: string;
  targetField: string;
  sourceDisplayName?: string;  // 메인 테이블 한글 컬럼명
  targetDisplayName?: string;  // 서브 테이블 한글 컬럼명
}

// 서브 테이블 정보 타입
export interface SubTableInfo {
  tableName: string;
  tableLabel?: string;                        // 테이블 한글명
  componentType: string;
  relationType: 'lookup' | 'source' | 'join' | 'reference' | 'parentMapping' | 'rightPanelRelation';
  fieldMappings?: FieldMappingInfo[];
  filterColumns?: string[];                   // 필터링에 사용되는 컬럼 목록
  // rightPanelRelation에서 추가 정보 (관계 유형 추론용)
  originalRelationType?: 'join' | 'detail';  // 원본 relation.type
  foreignKey?: string;                        // 디테일 테이블의 FK 컬럼
  leftColumn?: string;                        // 마스터 테이블의 선택 기준 컬럼
  // rightPanel.columns에서 외부 테이블 참조 정보
  joinedTables?: string[];                    // 참조하는 외부 테이블들 (예: ['customer_mng'])
  joinColumns?: string[];                     // 외부 테이블과 조인하는 FK 컬럼들 (예: ['customer_id'])
  joinColumnRefs?: Array<{                    // FK 컬럼 참조 정보 (어떤 테이블.컬럼에서 오는지)
    column: string;                           // FK 컬럼명 (예: 'customer_id')
    columnLabel: string;                      // FK 컬럼 한글명 (예: '거래처 ID')
    refTable: string;                         // 참조 테이블 (예: 'customer_mng')
    refTableLabel: string;                    // 참조 테이블 한글명 (예: '거래처 관리')
    refColumn: string;                        // 참조 컬럼 (예: 'customer_code')
  }>;
}

// 시각적 관계 유형 (시각화에서 사용)
export type VisualRelationType = 'filter' | 'hierarchy' | 'lookup' | 'mapping' | 'join';

// 관계 유형 추론 함수
export function inferVisualRelationType(subTable: SubTableInfo): VisualRelationType {
  // 1. split-panel-layout의 rightPanel.relation
  if (subTable.relationType === 'rightPanelRelation') {
    // 원본 relation.type 기반 구분
    if (subTable.originalRelationType === 'detail') {
      return 'hierarchy';  // 부모-자식 계층 구조 (같은 테이블 자기 참조)
    }
    return 'filter';  // 마스터-디테일 필터링
  }
  
  // 2. selected-items-detail-input의 parentDataMapping
  // parentDataMapping은 FK 관계를 정의하므로 조인으로 분류
  if (subTable.relationType === 'parentMapping') {
    return 'join';  // FK 조인 (sourceTable.sourceField → targetTable.targetField)
  }
  
  // 3. column_labels.reference_table
  if (subTable.relationType === 'reference') {
    return 'join';  // 실제 엔티티 조인 (LEFT JOIN 등)
  }
  
  // 4. autocomplete, entity-search
  if (subTable.relationType === 'lookup') {
    return 'lookup';  // 코드→명칭 변환
  }
  
  // 5. 기타 (source, join 등)
  return 'join';
}

// 저장 테이블 정보 타입
export interface SaveTableInfo {
  tableName: string;
  saveType: 'save' | 'edit' | 'delete' | 'transferData';
  componentType: string;
  isMainTable: boolean;
  mappingRules?: Array<{
    sourceField: string;
    targetField: string;
    transform?: string;
  }>;
}

export interface ScreenSubTablesData {
  screenId: number;
  screenName: string;
  mainTable: string;
  subTables: SubTableInfo[];
  saveTables?: SaveTableInfo[];  // 저장 대상 테이블 목록
}

// 여러 화면의 서브 테이블 정보 조회 (메인 테이블 → 서브 테이블 관계)
export async function getScreenSubTables(
  screenIds: number[]
): Promise<ApiResponse<Record<number, ScreenSubTablesData>>> {
  try {
    const response = await apiClient.post("/screen-groups/sub-tables/batch", { screenIds });
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}


// ============================================================
// 메뉴-화면그룹 동기화 API
// ============================================================

export interface SyncDetail {
  action: 'created' | 'linked' | 'skipped' | 'error';
  sourceName: string;
  sourceId: number | string;
  targetId?: number | string;
  reason?: string;
}

export interface SyncResult {
  success: boolean;
  created: number;
  linked: number;
  skipped: number;
  errors: string[];
  details: SyncDetail[];
}

export interface SyncStatus {
  screenGroups: { total: number; linked: number; unlinked: number };
  menuItems: { total: number; linked: number; unlinked: number };
  potentialMatches: Array<{ menuName: string; groupName: string; similarity: string }>;
}

// 동기화 상태 조회
export async function getMenuScreenSyncStatus(
  targetCompanyCode?: string
): Promise<ApiResponse<SyncStatus>> {
  try {
    const queryParams = targetCompanyCode ? `?targetCompanyCode=${targetCompanyCode}` : '';
    const response = await apiClient.get(`/screen-groups/sync/status${queryParams}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// 화면관리 → 메뉴 동기화
export async function syncScreenGroupsToMenu(
  targetCompanyCode?: string
): Promise<ApiResponse<SyncResult>> {
  try {
    const response = await apiClient.post("/screen-groups/sync/screen-to-menu", { targetCompanyCode });
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// 메뉴 → 화면관리 동기화
export async function syncMenuToScreenGroups(
  targetCompanyCode?: string
): Promise<ApiResponse<SyncResult>> {
  try {
    const response = await apiClient.post("/screen-groups/sync/menu-to-screen", { targetCompanyCode });
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// 전체 동기화 결과 타입
export interface AllCompaniesSyncResult {
  totalCompanies: number;
  successCount: number;
  failedCount: number;
  totalCreated: number;
  totalLinked: number;
  details: Array<{
    companyCode: string;
    companyName: string;
    direction: 'screens-to-menus' | 'menus-to-screens';
    created: number;
    linked: number;
    skipped: number;
    success: boolean;
    error?: string;
  }>;
}

// 전체 회사 동기화 (최고 관리자만)
export async function syncAllCompanies(): Promise<ApiResponse<AllCompaniesSyncResult>> {
  try {
    const response = await apiClient.post("/screen-groups/sync/all");
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

// ============================================================
// [PoC] screen_groups 기반 메뉴 트리 조회
// 화면관리 → 메뉴관리 통합 테스트용
// ============================================================

export interface MenuTreeItem {
  id: number;
  objid: number | string;
  name: string;
  name_kor: string;
  icon?: string;
  url: string | null;
  screen_id: number | null;
  screen_code?: string;
  screen_count: number;
  parent_id: number | null;
  level: number;
  display_order: number;
  is_active: boolean;
  menu_objid: number | null;
  children: MenuTreeItem[];
  // menu_info 호환 필드
  menu_name_kor: string;
  menu_url: string | null;
  parent_obj_id: string | null;
  seq: number;
  status: string;
}

export interface MenuTreeResult {
  data: MenuTreeItem[];
  stats: {
    totalGroups: number;
    groupsWithScreens: number;
    groupsWithMenuObjid: number;
    rootGroups: number;
  };
  flatList: Array<{
    objid: string;
    OBJID: string;
    menu_name_kor: string;
    MENU_NAME_KOR: string;
    menu_url: string | null;
    MENU_URL: string | null;
    parent_obj_id: string;
    PARENT_OBJ_ID: string;
    seq: number;
    SEQ: number;
    status: string;
    STATUS: string;
    menu_type: number;
    MENU_TYPE: number;
    screen_group_id: number;
    menu_objid: number | null;
  }>;
}

// [PoC] screen_groups 기반 메뉴 트리 조회
export async function getMenuTreeFromScreenGroups(targetCompanyCode?: string): Promise<ApiResponse<MenuTreeResult>> {
  try {
    const params = targetCompanyCode ? { targetCompanyCode } : {};
    const response = await apiClient.get("/screen-groups/menu-tree", { params });
    return response.data;
  } catch (error: any) {
    console.error("[PoC] 메뉴 트리 조회 실패:", error);
    return { success: false, error: error.message };
  }
}
