import { apiClient } from "./client";
import {
  ScreenDefinition,
  CreateScreenRequest,
  UpdateScreenRequest,
  PaginatedResponse,
  ScreenTemplate,
  LayoutData,
} from "@/types/screen";

// 화면 정의 관련 API
export const screenApi = {
  // 화면 목록 조회
  getScreens: async (params: {
    page?: number;
    size?: number;
    companyCode?: string;
    searchTerm?: string;
    excludePop?: boolean;
  }): Promise<PaginatedResponse<ScreenDefinition>> => {
    const response = await apiClient.get("/screen-management/screens", { params });
    const raw = response.data || {};
    const items: any[] = (raw.data ?? raw.items ?? []) as any[];
    const mapped: ScreenDefinition[] = items.map((it) => ({
      ...it,
      // 문자열로 온 날짜를 Date 객체로 변환 (이미 Date이면 그대로 유지)
      createdDate: it.createdDate ? new Date(it.createdDate) : undefined,
      updatedDate: it.updatedDate ? new Date(it.updatedDate) : undefined,
    }));

    const page = raw.page ?? params.page ?? 1;
    const size = raw.size ?? params.size ?? mapped.length;
    const total = raw.total ?? mapped.length;
    const totalPages = raw.totalPages ?? Math.max(1, Math.ceil(total / (size || 1)));

    return { data: mapped, total, page, size, totalPages };
  },

  // 화면 상세 조회
  getScreen: async (screenId: number): Promise<ScreenDefinition> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}`);
    const raw = response.data?.data || response.data;
    return {
      ...raw,
      createdDate: raw?.createdDate ? new Date(raw.createdDate) : undefined,
      updatedDate: raw?.updatedDate ? new Date(raw.updatedDate) : undefined,
    } as ScreenDefinition;
  },

  // 화면에 할당된 메뉴 조회
  getScreenMenu: async (screenId: number): Promise<{ menuObjid: number; menuName?: string } | null> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/menu`);
    return response.data?.data || null;
  },

  // 화면 생성
  createScreen: async (screenData: CreateScreenRequest): Promise<ScreenDefinition> => {
    const response = await apiClient.post("/screen-management/screens", screenData);
    return response.data.data;
  },

  // 화면 코드 자동 생성 (회사코드 + 순번)
  generateScreenCode: async (companyCode: string): Promise<string> => {
    const response = await apiClient.get(`/screen-management/generate-screen-code/${companyCode}`);
    return response.data.data.screenCode;
  },

  // 여러 개의 화면 코드 일괄 생성
  generateMultipleScreenCodes: async (companyCode: string, count: number): Promise<string[]> => {
    const response = await apiClient.post("/screen-management/generate-screen-codes", {
      companyCode,
      count,
    });
    return response.data.data.screenCodes;
  },

  // 화면 수정
  updateScreen: async (screenId: number, screenData: UpdateScreenRequest): Promise<ScreenDefinition> => {
    const response = await apiClient.put(`/screen-management/screens/${screenId}`, screenData);
    return response.data.data;
  },

  // 화면 정보 수정 (메타데이터만)
  updateScreenInfo: async (
    screenId: number,
    data: { screenName: string; description?: string; isActive: string },
  ): Promise<void> => {
    await apiClient.put(`/screen-management/screens/${screenId}/info`, data);
  },

  // 화면 테이블명 변경
  updateScreenTableName: async (screenId: number, tableName: string): Promise<void> => {
    await apiClient.patch(`/screen-management/screens/${screenId}/table-name`, { tableName });
  },

  // 화면 의존성 체크
  checkScreenDependencies: async (
    screenId: number,
  ): Promise<{
    hasDependencies: boolean;
    dependencies: Array<{
      screenId: number;
      screenName: string;
      screenCode: string;
      componentId: string;
      componentType: string;
      referenceType: string;
    }>;
  }> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/dependencies`);
    return response.data;
  },

  // 화면 삭제 (휴지통으로 이동)
  deleteScreen: async (screenId: number, deleteReason?: string, force?: boolean): Promise<void> => {
    await apiClient.delete(`/screen-management/screens/${screenId}`, {
      data: { deleteReason, force },
    });
  },

  // 활성 화면 일괄 삭제 (휴지통으로 이동)
  bulkDeleteScreens: async (
    screenIds: number[],
    deleteReason?: string,
    force?: boolean,
  ): Promise<{
    deletedCount: number;
    skippedCount: number;
    errors: Array<{ screenId: number; error: string }>;
  }> => {
    const response = await apiClient.delete("/screen-management/screens/bulk/delete", {
      data: { screenIds, deleteReason, force },
    });
    return response.data.result;
  },

  // 휴지통 화면 목록 조회
  getDeletedScreens: async (params: {
    page?: number;
    size?: number;
  }): Promise<
    PaginatedResponse<ScreenDefinition & { deletedDate?: Date; deletedBy?: string; deleteReason?: string }>
  > => {
    const response = await apiClient.get("/screen-management/screens/trash/list", { params });
    const raw = response.data || {};
    const items: any[] = (raw.data ?? raw.items ?? []) as any[];
    const mapped = items.map((it) => ({
      ...it,
      createdDate: it.createdDate ? new Date(it.createdDate) : undefined,
      updatedDate: it.updatedDate ? new Date(it.updatedDate) : undefined,
      deletedDate: it.deletedDate ? new Date(it.deletedDate) : undefined,
    }));

    const page = raw.page ?? params.page ?? 1;
    const size = raw.size ?? params.size ?? mapped.length;
    const total = raw.total ?? mapped.length;
    const totalPages = raw.totalPages ?? Math.max(1, Math.ceil(total / (size || 1)));

    return { data: mapped, total, page, size, totalPages };
  },

  // 휴지통 화면 일괄 영구 삭제
  bulkPermanentDeleteScreens: async (
    screenIds: number[],
  ): Promise<{
    deletedCount: number;
    skippedCount: number;
    errors: Array<{ screenId: number; error: string }>;
  }> => {
    const response = await apiClient.delete("/screen-management/screens/trash/bulk", {
      data: { screenIds },
    });
    return response.data.result;
  },

  // 화면 복원 (휴지통에서 복원)
  restoreScreen: async (screenId: number): Promise<void> => {
    await apiClient.post(`/screen-management/screens/${screenId}/restore`);
  },

  // 화면 영구 삭제
  permanentDeleteScreen: async (screenId: number): Promise<void> => {
    await apiClient.delete(`/screen-management/screens/${screenId}/permanent`);
  },

  // 화면 레이아웃 저장
  saveLayout: async (screenId: number, layoutData: LayoutData): Promise<void> => {
    await apiClient.post(`/screen-management/screens/${screenId}/layout`, layoutData);
  },

  // 화면 레이아웃 저장 (ScreenDesigner_new.tsx용)
  saveScreenLayout: async (screenId: number, layoutData: LayoutData): Promise<{ success: boolean; message?: string }> => {
    const response = await apiClient.post(`/screen-management/screens/${screenId}/layout`, layoutData);
    return response.data;
  },

  // 화면 레이아웃 조회 (기존)
  getLayout: async (screenId: number): Promise<LayoutData> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layout`);
    return response.data.data;
  },

  // 화면 레이아웃 조회 V1 (component_url + custom_config 기반)
  // 🔒 확정: component_url 필수, custom_config에 slot 포함, company_code 필터 적용
  getLayoutV1: async (screenId: number): Promise<LayoutData> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layout-v1`);
    return response.data.data;
  },

  // 화면 레이아웃 조회 V2 (1 레코드 방식 - url + overrides)
  // 🔒 확정: 화면당 1개 레코드, layout_data JSON에 모든 컴포넌트 포함
  getLayoutV2: async (screenId: number): Promise<any> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layout-v2`);
    return response.data.data;
  },

  // 화면 레이아웃 저장 V2 (1 레코드 방식 - url + overrides)
  saveLayoutV2: async (screenId: number, layoutData: any): Promise<void> => {
    await apiClient.post(`/screen-management/screens/${screenId}/layout-v2`, layoutData);
  },

  // 레이어 목록 조회
  getScreenLayers: async (screenId: number): Promise<any[]> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layers`);
    return response.data.data || [];
  },

  // 특정 레이어 레이아웃 조회
  getLayerLayout: async (screenId: number, layerId: number): Promise<any> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layers/${layerId}/layout`);
    return response.data.data;
  },

  // 레이어 삭제
  deleteLayer: async (screenId: number, layerId: number): Promise<void> => {
    await apiClient.delete(`/screen-management/screens/${screenId}/layers/${layerId}`);
  },

  // 레이어 조건 설정 업데이트
  updateLayerCondition: async (screenId: number, layerId: number, conditionConfig: any, layerName?: string): Promise<void> => {
    await apiClient.put(`/screen-management/screens/${screenId}/layers/${layerId}/condition`, { conditionConfig, layerName });
  },

  // ========================================
  // 조건부 영역(Zone) 관리
  // ========================================

  // Zone 목록 조회
  getScreenZones: async (screenId: number): Promise<any[]> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/zones`);
    return response.data.data || [];
  },

  // Zone 생성
  createZone: async (screenId: number, zoneData: {
    zone_name?: string;
    x: number;
    y: number;
    width: number;
    height: number;
    trigger_component_id?: string;
    trigger_operator?: string;
  }): Promise<any> => {
    const response = await apiClient.post(`/screen-management/screens/${screenId}/zones`, zoneData);
    return response.data.data;
  },

  // Zone 업데이트 (위치/크기/트리거)
  updateZone: async (zoneId: number, updates: {
    zone_name?: string;
    x?: number;
    y?: number;
    width?: number;
    height?: number;
    trigger_component_id?: string;
    trigger_operator?: string;
  }): Promise<void> => {
    await apiClient.put(`/screen-management/zones/${zoneId}`, updates);
  },

  // Zone 삭제
  deleteZone: async (zoneId: number): Promise<void> => {
    await apiClient.delete(`/screen-management/zones/${zoneId}`);
  },

  // Zone에 레이어 추가
  addLayerToZone: async (screenId: number, zoneId: number, conditionValue: string, layerName?: string): Promise<{ layerId: number }> => {
    const response = await apiClient.post(`/screen-management/screens/${screenId}/zones/${zoneId}/layers`, {
      conditionValue,
      layerName,
    });
    return response.data.data;
  },

  // ========================================
  // POP 레이아웃 관리 (모바일/태블릿)
  // ========================================

  // POP 레이아웃 조회
  getLayoutPop: async (screenId: number): Promise<any> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/layout-pop`);
    return response.data.data;
  },

  // POP 레이아웃 저장
  saveLayoutPop: async (screenId: number, layoutData: any): Promise<void> => {
    await apiClient.post(`/screen-management/screens/${screenId}/layout-pop`, layoutData);
  },

  // POP 레이아웃 삭제
  deleteLayoutPop: async (screenId: number): Promise<void> => {
    await apiClient.delete(`/screen-management/screens/${screenId}/layout-pop`);
  },

  // POP 레이아웃이 존재하는 화면 ID 목록 조회
  getScreenIdsWithPopLayout: async (): Promise<number[]> => {
    const response = await apiClient.get(`/screen-management/pop-layout-screen-ids`);
    return response.data.data || [];
  },

  // 연결된 모달 화면 감지
  detectLinkedModals: async (
    screenId: number,
  ): Promise<Array<{ screenId: number; screenName: string; screenCode: string }>> => {
    const response = await apiClient.get(`/screen-management/screens/${screenId}/linked-modals`);
    return response.data.data || [];
  },

  // 화면명 중복 체크
  checkDuplicateScreenName: async (companyCode: string, screenName: string): Promise<boolean> => {
    const response = await apiClient.post("/screen-management/screens/check-duplicate-name", {
      companyCode,
      screenName,
    });
    return response.data.data.isDuplicate || false;
  },

  // 화면 복사 (화면정보 + 레이아웃 모두 복사)
  copyScreen: async (
    sourceScreenId: number,
    copyData: {
      screenName: string;
      screenCode: string;
      description?: string;
    },
  ): Promise<ScreenDefinition> => {
    const response = await apiClient.post(`/screen-management/screens/${sourceScreenId}/copy`, copyData);
    return response.data.data;
  },

  // POP 화면 연결 분석 (다른 화면과의 참조 관계)
  analyzePopScreenLinks: async (
    screenId: number,
  ): Promise<{
    linkedScreenIds: number[];
    references: Array<{
      componentId: string;
      referenceType: string;
      targetScreenId: number;
    }>;
  }> => {
    const response = await apiClient.get(
      `/screen-management/screens/${screenId}/pop-links`,
    );
    return response.data.data || { linkedScreenIds: [], references: [] };
  },

  // POP 화면 배포 (다른 회사로 복사)
  deployPopScreens: async (data: {
    screens: Array<{
      sourceScreenId: number;
      screenName: string;
      screenCode: string;
    }>;
    targetCompanyCode: string;
    groupStructure?: {
      sourceGroupId: number;
      groupName: string;
      groupCode: string;
      screenIds: number[];
      children?: Array<{
        sourceGroupId: number;
        groupName: string;
        groupCode: string;
        screenIds: number[];
      }>;
    };
  }): Promise<{
    deployedScreens: Array<{
      sourceScreenId: number;
      newScreenId: number;
      screenName: string;
      screenCode: string;
    }>;
    createdGroups?: number;
  }> => {
    const response = await apiClient.post(
      `/screen-management/deploy-pop-screens`,
      data,
    );
    return response.data.data;
  },

  // 메인 화면 + 모달 화면들 일괄 복사
  copyScreenWithModals: async (
    sourceScreenId: number,
    copyData: {
      targetCompanyCode?: string; // 최고 관리자 전용: 다른 회사로 복사
      mainScreen: {
        screenName: string;
        screenCode: string;
        description?: string;
      };
      modalScreens: Array<{
        sourceScreenId: number;
        screenName: string;
        screenCode: string;
      }>;
    },
  ): Promise<{
    mainScreen: ScreenDefinition;
    modalScreens: ScreenDefinition[];
  }> => {
    const response = await apiClient.post(`/screen-management/screens/${sourceScreenId}/copy-with-modals`, copyData);
    return response.data.data;
  },
};

// 템플릿 관련 API
export const templateApi = {
  // 템플릿 목록 조회
  getTemplates: async (params: {
    companyCode?: string;
    templateType?: string;
    isPublic?: boolean;
  }): Promise<ScreenTemplate[]> => {
    const response = await apiClient.get("/screen-management/templates", { params });
    return response.data.data;
  },

  // 템플릿 상세 조회
  getTemplate: async (templateId: number): Promise<ScreenTemplate> => {
    const response = await apiClient.get(`/screen-management/templates/${templateId}`);
    return response.data.data;
  },

  // 템플릿 생성
  createTemplate: async (templateData: Partial<ScreenTemplate>): Promise<ScreenTemplate> => {
    const response = await apiClient.post("/screen-management/templates", templateData);
    return response.data.data;
  },

  // 템플릿 수정
  updateTemplate: async (templateId: number, templateData: Partial<ScreenTemplate>): Promise<ScreenTemplate> => {
    const response = await apiClient.put(`/screen-management/templates/${templateId}`, templateData);
    return response.data.data;
  },

  // 템플릿 삭제
  deleteTemplate: async (templateId: number): Promise<void> => {
    await apiClient.delete(`/screen-management/templates/${templateId}`);
  },
};

// 테이블 타입 관련 API
export const tableTypeApi = {
  // 테이블 목록 조회
  getTables: async (): Promise<
    Array<{ tableName: string; displayName: string; description: string; columnCount: string }>
  > => {
    const response = await apiClient.get("/table-management/tables");
    return response.data.data;
  },

  // 테이블 라벨 조회
  getTableLabel: async (tableName: string): Promise<{ tableLabel?: string; description?: string }> => {
    try {
      const response = await apiClient.get(`/table-management/tables/${tableName}/labels`);
      return response.data.data || {};
    } catch (error) {
      // 라벨이 없으면 빈 객체 반환
      return {};
    }
  },

  // 테이블 컬럼 정보 조회 (모든 컬럼)
  getColumns: async (tableName: string, bustCache: boolean = false): Promise<any[]> => {
    // bustCache: 캐시 우회 (테이블 타입 변경 후 즉시 반영 필요 시)
    const cacheParam = bustCache ? `&_t=${Date.now()}` : "";
    const response = await apiClient.get(`/table-management/tables/${tableName}/columns?size=1000${cacheParam}`);
    // 새로운 API 응답 구조에 맞게 수정: { columns, total, page, size, totalPages }
    const data = response.data.data || response.data;
    return data.columns || data || [];
  },

  // 컬럼 입력 타입 정보 조회
  getColumnInputTypes: async (tableName: string): Promise<any[]> => {
    const response = await apiClient.get(`/table-management/tables/${tableName}/web-types`);
    return response.data.data || [];
  },

  // 컬럼 웹 타입 설정
  setColumnWebType: async (
    tableName: string,
    columnName: string,
    webType: string,
    detailSettings?: Record<string, any>,
  ): Promise<void> => {
    await apiClient.put(`/table-management/tables/${tableName}/columns/${columnName}/web-type`, {
      webType,
      detailSettings,
    });
  },

  // 테이블 데이터 조회 (페이지네이션 + 검색)
  getTableData: async (
    tableName: string,
    params: {
      page?: number;
      size?: number;
      search?: Record<string, any>; // 검색 조건
      sortBy?: string;
      sortOrder?: "asc" | "desc";
    } = {},
  ): Promise<{
    data: Record<string, any>[];
    total: number;
    page: number;
    size: number;
    totalPages: number;
  }> => {
    // 🔒 멀티테넌시: company_code 자동 필터링 활성화
    const requestBody = {
      ...params,
      autoFilter: {
        enabled: true,
        filterColumn: "company_code",
        userField: "companyCode",
      },
    };

    const response = await apiClient.post(`/table-management/tables/${tableName}/data`, requestBody);
    const raw = response.data?.data || response.data;

    return {
      data: raw.data || [],
      total: raw.total || 0,
      page: raw.page || params.page || 1,
      size: raw.size || params.size || 10,
      totalPages: raw.totalPages || Math.ceil((raw.total || 0) / (params.size || 10)),
    };
  },

  // 데이터 추가
  addTableData: async (tableName: string, data: Record<string, any>): Promise<void> => {
    await apiClient.post(`/table-management/tables/${tableName}/add`, data);
  },

  // 데이터 수정
  editTableData: async (
    tableName: string,
    originalData: Record<string, any>,
    updatedData: Record<string, any>,
  ): Promise<void> => {
    await apiClient.put(`/table-management/tables/${tableName}/edit`, {
      originalData,
      updatedData,
    });
  },

  // 데이터 삭제 (단일 또는 다중)
  deleteTableData: async (tableName: string, data: Record<string, any>[] | { ids: string[] }): Promise<void> => {
    await apiClient.delete(`/table-management/tables/${tableName}/delete`, { data });
  },

  // 🆕 단일 레코드 조회 (자동 입력용)
  getTableRecord: async (
    tableName: string,
    filterColumn: string,
    filterValue: any,
    displayColumn: string,
  ): Promise<{ value: any; record: Record<string, any> }> => {
    const response = await apiClient.post(`/table-management/tables/${tableName}/record`, {
      filterColumn,
      filterValue,
      displayColumn,
    });
    return response.data.data;
  },
};

// 메뉴-화면 할당 관련 API
export const menuScreenApi = {
  // 화면을 메뉴에 할당
  assignScreenToMenu: async (screenId: number, menuObjid: number, displayOrder?: number): Promise<void> => {
    await apiClient.post(`/screen-management/screens/${screenId}/assign-menu`, {
      menuObjid,
      displayOrder,
    });
  },

  // 메뉴별 할당된 화면 목록 조회
  getScreensByMenu: async (menuObjid: number): Promise<ScreenDefinition[]> => {
    const response = await apiClient.get(`/screen-management/menus/${menuObjid}/screens`);
    return response.data.data.map((screen: any) => ({
      ...screen,
      createdDate: screen.createdDate ? new Date(screen.createdDate) : new Date(),
      updatedDate: screen.updatedDate ? new Date(screen.updatedDate) : new Date(),
    }));
  },

  // 화면-메뉴 할당 해제
  unassignScreenFromMenu: async (screenId: number, menuObjid: number): Promise<void> => {
    await apiClient.delete(`/screen-management/screens/${screenId}/menus/${menuObjid}`);
  },

};

// 그룹 복제 완료 후 탭 컴포넌트의 screenId 참조 일괄 업데이트 (별도 export)
export async function updateTabScreenReferences(
  targetScreenIds: number[],
  screenIdMap: { [key: number]: number }
): Promise<{ success: boolean; updated: number; details: string[] }> {
  const response = await apiClient.post("/screen-management/screens/update-tab-references", {
    targetScreenIds,
    screenIdMap,
  });
  return response.data;
}
