"use client";

import { useState, useCallback, useMemo, useRef } from "react";
import { apiClient } from "@/lib/api/client";
import { ItemRoutingConfig, ItemData, RoutingVersionData, RoutingDetailData, ColumnDef } from "../types";
import { defaultConfig } from "../config";

const API_BASE = "/process-work-standard";

/** 표시 컬럼 목록에서 기본(item_name, item_code) 외 추가 컬럼만 추출 */
function getExtraColumnNames(columns?: ColumnDef[]): string {
  if (!columns || columns.length === 0) return "";
  return columns
    .map((c) => c.name)
    .filter((n) => n && n !== "item_name" && n !== "item_code")
    .join(",");
}

export function useItemRouting(configPartial: Partial<ItemRoutingConfig>) {
  const configKey = useMemo(
    () => JSON.stringify(configPartial),
    [configPartial]
  );

  const config: ItemRoutingConfig = useMemo(() => ({
    ...defaultConfig,
    ...configPartial,
    dataSource: { ...defaultConfig.dataSource, ...configPartial?.dataSource },
    modals: { ...defaultConfig.modals, ...configPartial?.modals },
    processColumns: configPartial?.processColumns?.length
      ? configPartial.processColumns
      : defaultConfig.processColumns,
  }), [configKey]);

  const configRef = useRef(config);
  configRef.current = config;

  const [items, setItems] = useState<ItemData[]>([]);
  const [allItems, setAllItems] = useState<ItemData[]>([]);
  const [versions, setVersions] = useState<RoutingVersionData[]>([]);
  const [details, setDetails] = useState<RoutingDetailData[]>([]);
  const [loading, setLoading] = useState(false);

  const [selectedItemCode, setSelectedItemCode] = useState<string | null>(null);
  const [selectedItemName, setSelectedItemName] = useState<string | null>(null);
  const [selectedVersionId, setSelectedVersionId] = useState<string | null>(null);

  const isRegisteredMode = config.itemListMode === "registered";

  /** API 기본 파라미터 생성 */
  const buildBaseParams = useCallback((search?: string, columns?: ColumnDef[]) => {
    const ds = configRef.current.dataSource;
    const extra = getExtraColumnNames(columns);
    const filters = configRef.current.itemFilterConditions;
    const params: Record<string, string> = {
      tableName: ds.itemTable,
      nameColumn: ds.itemNameColumn,
      codeColumn: ds.itemCodeColumn,
      routingTable: ds.routingVersionTable,
      routingFkColumn: ds.routingVersionFkColumn,
    };
    if (search) params.search = search;
    if (extra) params.extraColumns = extra;
    if (filters && filters.length > 0) {
      params.filterConditions = JSON.stringify(filters);
    }
    return new URLSearchParams(params);
  }, []);

  // ────────────────────────────────────────
  // 품목 목록 조회 (all 모드)
  // ────────────────────────────────────────
  const fetchItems = useCallback(
    async (search?: string) => {
      try {
        setLoading(true);
        const cols = configRef.current.itemDisplayColumns;
        const params = buildBaseParams(search, cols);
        const res = await apiClient.get(`${API_BASE}/items?${params}`);
        if (res.data?.success) {
          const data = res.data.data || [];
          if (configRef.current.itemListMode !== "registered") {
            setItems(data);
          }
          return data;
        }
      } catch (err) {
        console.error("품목 조회 실패", err);
      } finally {
        setLoading(false);
      }
      return [];
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [configKey, buildBaseParams]
  );

  // ────────────────────────────────────────
  // 등록 품목 조회 (registered 모드)
  // ────────────────────────────────────────
  const fetchRegisteredItems = useCallback(
    async (search?: string) => {
      const screenCode = configRef.current.screenCode;
      if (!screenCode) {
        console.warn("screenCode가 설정되지 않았습니다");
        setItems([]);
        return;
      }
      try {
        setLoading(true);
        const ds = configRef.current.dataSource;
        const cols = configRef.current.itemDisplayColumns;
        const extra = getExtraColumnNames(cols);
        const params = new URLSearchParams({
          tableName: ds.itemTable,
          nameColumn: ds.itemNameColumn,
          codeColumn: ds.itemCodeColumn,
          routingTable: ds.routingVersionTable,
          routingFkColumn: ds.routingVersionFkColumn,
          ...(search ? { search } : {}),
          ...(extra ? { extraColumns: extra } : {}),
        });
        const res = await apiClient.get(
          `${API_BASE}/registered-items/${encodeURIComponent(screenCode)}?${params}`
        );
        if (res.data?.success) {
          setItems(res.data.data || []);
        }
      } catch (err) {
        console.error("등록 품목 조회 실패", err);
      } finally {
        setLoading(false);
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [configKey]
  );

  // ────────────────────────────────────────
  // 전체 품목 조회 (등록 팝업용 - 필터+추가컬럼 적용)
  // ────────────────────────────────────────
  const fetchAllItems = useCallback(
    async (search?: string) => {
      try {
        const cols = configRef.current.modalDisplayColumns;
        const params = buildBaseParams(search, cols);
        const res = await apiClient.get(`${API_BASE}/items?${params}`);
        if (res.data?.success) {
          setAllItems(res.data.data || []);
        }
      } catch (err) {
        console.error("전체 품목 조회 실패", err);
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [configKey, buildBaseParams]
  );

  // ────────────────────────────────────────
  // 품목 등록/제거 (registered 모드)
  // ────────────────────────────────────────
  const registerItem = useCallback(
    async (itemId: string, itemCode: string) => {
      const screenCode = configRef.current.screenCode;
      if (!screenCode) return false;
      try {
        const res = await apiClient.post(`${API_BASE}/registered-items`, {
          screenCode,
          itemId,
          itemCode,
        });
        if (res.data?.success) {
          await fetchRegisteredItems();
          return true;
        }
      } catch (err) {
        console.error("품목 등록 실패", err);
      }
      return false;
    },
    [fetchRegisteredItems]
  );

  const registerItemsBatch = useCallback(
    async (itemList: { itemId: string; itemCode: string }[]) => {
      const screenCode = configRef.current.screenCode;
      if (!screenCode) return false;
      try {
        const res = await apiClient.post(`${API_BASE}/registered-items/batch`, {
          screenCode,
          items: itemList,
        });
        if (res.data?.success) {
          await fetchRegisteredItems();
          return true;
        }
      } catch (err) {
        console.error("품목 일괄 등록 실패", err);
      }
      return false;
    },
    [fetchRegisteredItems]
  );

  const unregisterItem = useCallback(
    async (registeredId: string) => {
      try {
        const res = await apiClient.delete(`${API_BASE}/registered-items/${registeredId}`);
        if (res.data?.success) {
          if (selectedItemCode) {
            const removedItem = items.find((i) => i.registered_id === registeredId);
            if (removedItem) {
              const removedCode = removedItem.item_code || removedItem[configRef.current.dataSource.itemCodeColumn];
              if (selectedItemCode === removedCode) {
                setSelectedItemCode(null);
                setSelectedItemName(null);
                setSelectedVersionId(null);
                setVersions([]);
                setDetails([]);
              }
            }
          }
          await fetchRegisteredItems();
          return true;
        }
      } catch (err) {
        console.error("등록 품목 제거 실패", err);
      }
      return false;
    },
    [selectedItemCode, items, fetchRegisteredItems]
  );

  // ────────────────────────────────────────
  // 라우팅 버전/공정 관련 (기존 동일)
  // ────────────────────────────────────────
  const fetchVersions = useCallback(
    async (itemCode: string) => {
      try {
        const ds = configRef.current.dataSource;
        const params = new URLSearchParams({
          routingVersionTable: ds.routingVersionTable,
          routingDetailTable: ds.routingDetailTable,
          routingFkColumn: ds.routingVersionFkColumn,
          processTable: ds.processTable,
          processNameColumn: ds.processNameColumn,
          processCodeColumn: ds.processCodeColumn,
        });
        const res = await apiClient.get(
          `${API_BASE}/items/${encodeURIComponent(itemCode)}/routings?${params}`
        );
        if (res.data?.success) {
          const routingData = res.data.data || [];
          setVersions(routingData);
          return routingData;
        }
      } catch (err) {
        console.error("라우팅 버전 조회 실패", err);
      }
      return [];
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [configKey]
  );

  const fetchDetails = useCallback(
    async (versionId: string) => {
      try {
        setLoading(true);
        const ds = configRef.current.dataSource;
        const searchConditions = {
          [ds.routingDetailFkColumn]: { value: versionId, operator: "equals" },
        };
        const params = new URLSearchParams({
          page: "1",
          size: "1000",
          search: JSON.stringify(searchConditions),
          sortBy: "seq_no",
          sortOrder: "ASC",
          enableEntityJoin: "true",
        });
        const res = await apiClient.get(
          `/table-management/tables/${ds.routingDetailTable}/data-with-joins?${params}`
        );
        if (res.data?.success) {
          const result = res.data.data;
          setDetails(Array.isArray(result) ? result : result?.data || []);
        }
      } catch (err) {
        console.error("공정 상세 조회 실패", err);
      } finally {
        setLoading(false);
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [configKey]
  );

  const selectItem = useCallback(
    async (itemCode: string, itemName: string) => {
      setSelectedItemCode(itemCode);
      setSelectedItemName(itemName);
      setSelectedVersionId(null);
      setDetails([]);
      const versionList = await fetchVersions(itemCode);
      if (versionList.length > 0) {
        const defaultVersion = versionList.find((v: RoutingVersionData) => v.is_default);
        const targetVersion = defaultVersion || (configRef.current.autoSelectFirstVersion ? versionList[0] : null);
        if (targetVersion) {
          setSelectedVersionId(targetVersion.id);
          await fetchDetails(targetVersion.id);
        }
      }
    },
    [fetchVersions, fetchDetails]
  );

  const selectVersion = useCallback(
    async (versionId: string) => {
      setSelectedVersionId(versionId);
      await fetchDetails(versionId);
    },
    [fetchDetails]
  );

  const refreshVersions = useCallback(async () => {
    if (selectedItemCode) {
      const versionList = await fetchVersions(selectedItemCode);
      if (selectedVersionId) {
        await fetchDetails(selectedVersionId);
      } else if (versionList.length > 0) {
        const lastVersion = versionList[versionList.length - 1];
        setSelectedVersionId(lastVersion.id);
        await fetchDetails(lastVersion.id);
      }
    }
  }, [selectedItemCode, selectedVersionId, fetchVersions, fetchDetails]);

  const refreshDetails = useCallback(async () => {
    if (selectedVersionId) {
      await fetchDetails(selectedVersionId);
    }
  }, [selectedVersionId, fetchDetails]);

  const deleteDetail = useCallback(
    async (detailId: string) => {
      try {
        const ds = configRef.current.dataSource;
        const res = await apiClient.delete(
          `/table-management/tables/${ds.routingDetailTable}/delete`,
          { data: [{ id: detailId }] }
        );
        if (res.data?.success) { await refreshDetails(); return true; }
      } catch (err) { console.error("공정 삭제 실패", err); }
      return false;
    },
    [refreshDetails]
  );

  const deleteVersion = useCallback(
    async (versionId: string) => {
      try {
        const ds = configRef.current.dataSource;
        const res = await apiClient.delete(
          `/table-management/tables/${ds.routingVersionTable}/delete`,
          { data: [{ id: versionId }] }
        );
        if (res.data?.success) {
          if (selectedVersionId === versionId) { setSelectedVersionId(null); setDetails([]); }
          await refreshVersions();
          return true;
        }
      } catch (err) { console.error("버전 삭제 실패", err); }
      return false;
    },
    [selectedVersionId, refreshVersions]
  );

  const setDefaultVersion = useCallback(
    async (versionId: string) => {
      try {
        const ds = configRef.current.dataSource;
        const res = await apiClient.put(`${API_BASE}/versions/${versionId}/set-default`, {
          routingVersionTable: ds.routingVersionTable,
          routingFkColumn: ds.routingVersionFkColumn,
        });
        if (res.data?.success) {
          if (selectedItemCode) await fetchVersions(selectedItemCode);
          return true;
        }
      } catch (err) { console.error("기본 버전 설정 실패", err); }
      return false;
    },
    [selectedItemCode, fetchVersions]
  );

  const unsetDefaultVersion = useCallback(
    async (versionId: string) => {
      try {
        const ds = configRef.current.dataSource;
        const res = await apiClient.put(`${API_BASE}/versions/${versionId}/unset-default`, {
          routingVersionTable: ds.routingVersionTable,
        });
        if (res.data?.success) {
          if (selectedItemCode) await fetchVersions(selectedItemCode);
          return true;
        }
      } catch (err) { console.error("기본 버전 해제 실패", err); }
      return false;
    },
    [selectedItemCode, fetchVersions]
  );

  return {
    config,
    items,
    allItems,
    versions,
    details,
    loading,
    selectedItemCode,
    selectedItemName,
    selectedVersionId,
    isRegisteredMode,
    fetchItems,
    fetchRegisteredItems,
    fetchAllItems,
    registerItem,
    registerItemsBatch,
    unregisterItem,
    selectItem,
    selectVersion,
    refreshVersions,
    refreshDetails,
    deleteDetail,
    deleteVersion,
    setDefaultVersion,
    unsetDefaultVersion,
  };
}
