/**
 * 작업자 화면 서버 액션
 * API 연동 (2025-12-26 초기, 2026-02-06 options + step-progress 확장)
 *
 * WorkOrders API를 호출하고 WorkerScreen에 맞는 형식으로 변환
 */

'use server';


import { executeServerAction } from '@/lib/api/execute-server-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type { WorkOrder, WorkOrderStatus } from '../ProductionDashboard/types';
import type { WorkItemData, WorkStepData, ProcessTab } from './types';

// ===== API 타입 =====
interface WorkOrderApiItem {
  id: number;
  work_order_no: string;
  project_name: string | null;
  process_id: number | null;
  process?: {
    id: number;
    process_name: string;
    process_code: string;
    department?: string | null;
    options?: {
      needs_inspection?: boolean;
      needs_work_log?: boolean;
    } | null;
  };
  /** @deprecated process_id + process relation 사용 */
  process_type?: 'screen' | 'slat' | 'bending';
  status: 'unassigned' | 'pending' | 'waiting' | 'in_progress' | 'completed' | 'shipped' | 'cancelled';
  scheduled_date: string | null;
  memo: string | null;
  created_at: string;
  sales_order?: {
    id: number;
    order_no: string;
    item?: { id: number; code: string; name: string } | null;
    client?: { id: number; name: string };
    client_contact?: string;
    options?: { manager_name?: string; [key: string]: unknown };
    root_nodes_count?: number;
  };
  team_id?: number | null;
  team?: { id: number; name: string } | null;
  assignee?: { id: number; name: string };
  assignees?: { id: number; user_id: number; user?: { id: number; name: string } }[];
  items?: {
    id: number;
    item_name: string;
    item_id?: number | null;
    item?: { id: number; code: string; name: string } | null;
    quantity: number;
    specification?: string | null;
    options?: Record<string, unknown> | null;
    source_order_item?: {
      id: number;
      order_node_id: number | null;
      item_code?: string | null;
      floor_code?: string | null;
      symbol_code?: string | null;
      node?: { id: number; name: string; code: string } | null;
    } | null;
    material_inputs?: {
      id: number;
      stock_lot_id: number;
      item_id: number;
      qty: number;
      input_by: number | null;
      input_at: string | null;
      stock_lot?: { id: number; lot_no: string } | null;
      item?: { id: number; code: string; name: string; unit: string } | null;
    }[];
  }[];
}

// ===== 상태 변환 =====
function mapApiStatus(status: WorkOrderApiItem['status']): WorkOrderStatus {
  switch (status) {
    case 'in_progress':
      return 'inProgress';
    case 'completed':
    case 'shipped':
      return 'completed';
    default:
      return 'waiting';
  }
}

// ===== API → WorkOrder 변환 =====
function transformToWorkerScreenFormat(api: WorkOrderApiItem): WorkOrder {
  const totalQuantity = (api.items || []).reduce((sum, item) => sum + Number(item.quantity), 0);
  const productCode = (api.items?.[0]?.options?.product_code as string) || api.sales_order?.item?.code || '-';
  const productName = (api.items?.[0]?.options?.product_name as string) || api.items?.[0]?.item_name || '-';

  // 납기일 계산 (지연 여부)
  const dueDate = api.scheduled_date || '';
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const due = dueDate ? new Date(dueDate) : null;
  const isDelayed = due ? due < today : false;
  const delayDays = due && isDelayed
    ? Math.ceil((today.getTime() - due.getTime()) / (1000 * 60 * 60 * 24))
    : undefined;

  // process relation → processCode/processName 매핑
  // 신규: process relation 사용, 폴백: deprecated process_type 필드
  const rawProcessName = api.process?.process_name || '';
  const rawProcessCode = api.process?.process_code || '';

  // 한글 공정명 → 탭 키 매핑 (필터링에 사용)
  const nameToTab: Record<string, { code: string; name: string }> = {
    '스크린': { code: 'screen', name: '스크린' },
    '슬랫': { code: 'slat', name: '슬랫' },
    '절곡': { code: 'bending', name: '절곡' },
  };

  // 1차: process relation의 process_name으로 매핑
  let processInfo = Object.entries(nameToTab).find(
    ([key]) => rawProcessName.includes(key)
  )?.[1];

  // 2차: deprecated process_type 폴백
  if (!processInfo && api.process_type) {
    const legacyMap: Record<string, { code: string; name: string }> = {
      screen: { code: 'screen', name: '스크린' },
      slat: { code: 'slat', name: '슬랫' },
      bending: { code: 'bending', name: '절곡' },
    };
    processInfo = legacyMap[api.process_type];
  }

  // 3차: 그래도 없으면 원시값 사용
  if (!processInfo) {
    processInfo = { code: rawProcessCode || 'unknown', name: rawProcessName || '알수없음' };
  }

  // 아이템을 개소(order_node_id)별로 그룹핑 (floor_code/symbol_code는 표시용)
  const nodeMap = new Map<string, { nodeId: number | null; nodeName: string; items: typeof api.items }>();
  for (const item of (api.items || [])) {
    const nodeId = item.source_order_item?.order_node_id ?? null;
    const floorCode = item.source_order_item?.floor_code;
    const symbolCode = item.source_order_item?.symbol_code;
    const floorLabel = [floorCode, symbolCode].filter(v => v && v !== '-').join('/');
    const nodeName = floorLabel || item.source_order_item?.node?.name || '미지정';
    const key = nodeId != null ? String(nodeId) : (floorLabel || `unassigned-${item.id}`);
    if (!nodeMap.has(key)) {
      nodeMap.set(key, { nodeId, nodeName, items: [] });
    }
    nodeMap.get(key)!.items!.push(item);
  }

  const nodeGroups = Array.from(nodeMap.values()).map((g) => ({
    nodeId: g.nodeId,
    nodeName: g.nodeName,
    items: (g.items || []).map((it) => ({
      id: it.id,
      itemCode: it.item?.code || it.source_order_item?.item_code || null,
      itemName: it.item_name,
      quantity: Number(it.quantity),
      specification: it.specification,
      options: it.options,
      materialInputs: (it.material_inputs || []).map((mi) => ({
        id: mi.id,
        stockLotId: mi.stock_lot_id,
        lotNo: mi.stock_lot?.lot_no || null,
        itemId: mi.item_id,
        materialName: mi.item?.name || null,
        qty: Number(mi.qty),
        unit: mi.item?.unit || 'EA',
      })),
    })),
    totalQuantity: (g.items || []).reduce((sum, it) => sum + Number(it.quantity), 0),
  }));

  return {
    id: String(api.id),
    orderNo: api.work_order_no,
    productCode,
    productName,
    processCode: processInfo.code,
    processName: processInfo.name,
    client: api.sales_order?.client?.name || '-',
    projectName: api.project_name || '-',
    assignees: api.assignees?.length
      ? api.assignees.map((a) => a.user?.name || '').filter(Boolean)
      : api.assignee ? [api.assignee.name] : [],
    quantity: totalQuantity,
    shutterCount: nodeGroups.length || api.sales_order?.root_nodes_count || 0,
    dueDate,
    priority: 5, // 기본 우선순위
    status: mapApiStatus(api.status),
    isUrgent: false, // 긴급 여부는 별도 필드 필요
    isDelayed,
    delayDays,
    instruction: api.memo || undefined,
    salesOrderNo: api.sales_order?.order_no || undefined,
    salesManager: api.sales_order?.options?.manager_name as string || undefined,
    managerPhone: api.sales_order?.client_contact || undefined,
    assigneeId: api.assignee?.id ?? null,
    teamId: api.team_id ?? null,
    teamName: api.team?.name || undefined,
    processDepartment: api.process?.department || undefined,
    scheduledDate: api.scheduled_date || undefined,
    createdAt: api.created_at,
    processOptions: {
      needsInspection: api.process?.options?.needs_inspection ?? false,
      needsWorkLog: api.process?.options?.needs_work_log ?? false,
    },
    nodeGroups,
  };
}

const API_URL = process.env.NEXT_PUBLIC_API_URL;

// ===== 내 작업 목록 조회 =====
export async function getMyWorkOrders(): Promise<{
  success: boolean;
  data: WorkOrder[];
  error?: string;
}> {
  interface PaginatedWO { data: WorkOrderApiItem[] }
  const result = await executeServerAction<PaginatedWO>({
    url: `${API_URL}/api/v1/work-orders?per_page=100&worker_screen=1`,
    errorMessage: '작업 목록 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  // completed/shipped도 포함 (사이드바 완료 탭에서 표시)
  const workOrders = (result.data.data || [])
    .filter((item) => item.status !== 'cancelled')
    .map(transformToWorkerScreenFormat);
  return { success: true, data: workOrders };
}

// ===== 작업 완료 처리 =====
export async function completeWorkOrder(
  id: string,
  materials?: { materialId: number; quantity: number; lotNo?: string }[]
): Promise<{ success: boolean; lotNo?: string; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${id}/status`,
    method: 'PATCH',
    body: { status: 'completed', materials },
    errorMessage: '작업 완료 처리에 실패했습니다.',
  });
  if (!result.success) return { success: false, error: result.error };
  // 백엔드에서 생성한 실제 LOT 번호 사용
  const lotNo = (result.data as { lot_no?: string })?.lot_no;
  return { success: true, lotNo };
}

// ===== 작업지시 작업정보 업데이트 (생산일자/부서/담당자) =====
export async function updateWorkOrderInfo(
  id: string,
  data: { scheduled_date?: string; team_id?: number | null; assignee_id?: number | null }
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${id}`,
    method: 'PUT',
    body: data,
    errorMessage: '작업정보 저장에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 자재 목록 조회 (로트 기준) =====
export interface MaterialForInput {
  stockLotId: number | null;  // StockLot ID (null이면 재고 없음)
  itemId: number;
  lotNo: string | null;       // 실제 입고 로트번호
  materialCode: string;
  materialName: string;
  specification: string;
  unit: string;
  requiredQty: number;        // 필요 수량
  lotAvailableQty: number;    // 로트별 가용 수량
  fifoRank: number;
  // dynamic_bom 추가 필드 (절곡 세부품목용)
  workOrderItemId?: number;   // 개소(작업지시품목) ID
  lotPrefix?: string;         // LOT prefix (RS, RM 등)
  partType?: string;          // 파트 타입 (finish, body 등)
  category?: string;          // 카테고리 (guideRail, bottomBar 등)
}

export async function getMaterialsForWorkOrder(
  workOrderId: string
): Promise<{
  success: boolean;
  data: MaterialForInput[];
  error?: string;
}> {
  interface MaterialApiItem {
    stock_lot_id: number | null; item_id: number; lot_no: string | null;
    material_code: string; material_name: string; specification: string;
    unit: string; required_qty: number; lot_available_qty: number; fifo_rank: number;
    // dynamic_bom 추가 필드
    work_order_item_id?: number; lot_prefix?: string; part_type?: string; category?: string;
  }
  const result = await executeServerAction<MaterialApiItem[]>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/materials`,
    errorMessage: '자재 목록 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  return {
    success: true,
    data: result.data.map((item) => ({
      stockLotId: item.stock_lot_id, itemId: item.item_id, lotNo: item.lot_no,
      materialCode: item.material_code, materialName: item.material_name,
      specification: item.specification ?? '', unit: item.unit,
      requiredQty: item.required_qty, lotAvailableQty: item.lot_available_qty, fifoRank: item.fifo_rank,
      workOrderItemId: item.work_order_item_id, lotPrefix: item.lot_prefix,
      partType: item.part_type, category: item.category,
    })),
  };
}

// ===== 자재 투입 등록 (로트별 수량) =====
export async function registerMaterialInput(
  workOrderId: string,
  inputs: { stock_lot_id: number; qty: number; work_order_item_id?: number }[]
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs`,
    method: 'POST',
    body: { inputs },
    errorMessage: '자재 투입 등록에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 개소별 자재 목록 조회 =====
export interface MaterialForItemInput extends MaterialForInput {
  alreadyInputted: number;       // 이미 투입된 수량
  remainingRequiredQty: number;  // 남은 필요 수량
  lotInputtedQty: number;        // 해당 LOT의 기투입 수량
  bomGroupKey?: string;          // BOM 엔트리별 고유 그룹키 (category+partType 기반)
}

export async function getMaterialsForItem(
  workOrderId: string,
  itemId: number
): Promise<{
  success: boolean;
  data: MaterialForItemInput[];
  error?: string;
}> {
  interface MaterialItemApiItem {
    stock_lot_id: number | null; item_id: number; lot_no: string | null;
    material_code: string; material_name: string; specification: string;
    unit: string; bom_qty: number; required_qty: number;
    already_inputted: number; remaining_required_qty: number; lot_inputted_qty: number;
    lot_available_qty: number; fifo_rank: number;
    lot_qty: number; lot_reserved_qty: number;
    receipt_date: string | null; supplier: string | null;
    // dynamic_bom 추가 필드
    work_order_item_id?: number; lot_prefix?: string; part_type?: string; category?: string;
    bom_group_key?: string;
  }
  const result = await executeServerAction<MaterialItemApiItem[]>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/materials`,
    errorMessage: '개소별 자재 목록 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  return {
    success: true,
    data: result.data.map((item) => ({
      stockLotId: item.stock_lot_id, itemId: item.item_id, lotNo: item.lot_no,
      materialCode: item.material_code, materialName: item.material_name,
      specification: item.specification ?? '', unit: item.unit,
      requiredQty: item.required_qty, lotAvailableQty: item.lot_available_qty,
      fifoRank: item.fifo_rank,
      alreadyInputted: item.already_inputted,
      remainingRequiredQty: item.remaining_required_qty,
      lotInputtedQty: item.lot_inputted_qty ?? 0,
      workOrderItemId: item.work_order_item_id, lotPrefix: item.lot_prefix,
      partType: item.part_type, category: item.category,
      bomGroupKey: item.bom_group_key,
    })),
  };
}

// ===== 개소별 자재 투입 등록 =====
export async function registerMaterialInputForItem(
  workOrderId: string,
  itemId: number,
  inputs: { stock_lot_id: number; qty: number; bom_group_key?: string }[],
  replace = false
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`,
    method: 'POST',
    body: { inputs, replace },
    errorMessage: '개소별 자재 투입 등록에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 개소별 자재 투입 이력 조회 =====
export interface MaterialInputHistoryItem {
  id: number;
  stockLotId: number;
  lotNo: string | null;
  itemId: number;
  materialCode: string | null;
  materialName: string | null;
  qty: number;
  unit: string;
  inputBy: number | null;
  inputByName: string | null;
  inputAt: string | null;
}

export async function getMaterialInputsForItem(
  workOrderId: string,
  itemId: number
): Promise<{
  success: boolean;
  data: MaterialInputHistoryItem[];
  error?: string;
}> {
  interface HistoryApiItem {
    id: number; stock_lot_id: number; lot_no: string | null;
    item_id: number; material_code: string | null; material_name: string | null;
    qty: number; unit: string;
    input_by: number | null; input_by_name: string | null; input_at: string | null;
  }
  const result = await executeServerAction<HistoryApiItem[]>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/material-inputs`,
    errorMessage: '개소별 투입 이력 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  return {
    success: true,
    data: result.data.map((item) => ({
      id: item.id, stockLotId: item.stock_lot_id, lotNo: item.lot_no,
      itemId: item.item_id, materialCode: item.material_code,
      materialName: item.material_name, qty: item.qty, unit: item.unit,
      inputBy: item.input_by, inputByName: item.input_by_name, inputAt: item.input_at,
    })),
  };
}

// ===== 자재 투입 삭제 (재고 복원) =====
export async function deleteMaterialInput(
  workOrderId: string,
  inputId: number
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`,
    method: 'DELETE',
    errorMessage: '자재 투입 삭제에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 자재 투입 수량 수정 =====
export async function updateMaterialInput(
  workOrderId: string,
  inputId: number,
  qty: number
): Promise<{ success: boolean; data?: { id: number; qty: number; changed: boolean }; error?: string }> {
  const result = await executeServerAction<{ id: number; qty: number; changed: boolean }>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/material-inputs/${inputId}`,
    method: 'PATCH',
    body: { qty },
    errorMessage: '자재 투입 수정에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 이슈 보고 =====
export async function reportIssue(
  workOrderId: string,
  data: {
    title: string;
    description?: string;
    priority?: 'low' | 'medium' | 'high';
  }
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/issues`,
    method: 'POST',
    body: data,
    errorMessage: '이슈 보고에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 공정 단계 조회 =====
export interface ProcessStepItem {
  id: string;
  itemNo: string;
  location: string;
  isPriority: boolean;
  spec: string;
  material: string;
  lot: string;
}

export interface ProcessStep {
  id: string;
  stepNo: number;
  name: string;
  isInspection?: boolean;
  completed: number;
  total: number;
  items: ProcessStepItem[];
}

export async function getProcessSteps(
  workOrderId: string
): Promise<{
  success: boolean;
  data: ProcessStep[];
  error?: string;
}> {
  interface StepApiItem {
    id: number; step_no: number; name: string; is_inspection?: boolean;
    completed: number; total: number;
    items?: { id: number; item_no: string; location: string; is_priority: boolean; spec: string; material: string; lot: string }[];
  }
  const result = await executeServerAction<StepApiItem[]>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/process-steps`,
    errorMessage: '공정 단계 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  return {
    success: true,
    data: result.data.map((step) => ({
      id: String(step.id), stepNo: step.step_no, name: step.name,
      isInspection: step.is_inspection, completed: step.completed, total: step.total,
      items: (step.items || []).map((item) => ({
        id: String(item.id), itemNo: item.item_no, location: item.location,
        isPriority: item.is_priority, spec: item.spec, material: item.material, lot: item.lot,
      })),
    })),
  };
}

// ===== 검사 요청 =====
export async function requestInspection(
  workOrderId: string,
  stepId: string
): Promise<{ success: boolean; error?: string }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/process-steps/${stepId}/inspection-request`,
    method: 'POST',
    body: {},
    errorMessage: '검사 요청에 실패했습니다.',
  });
  return { success: result.success, error: result.error };
}

// ===== 공정 단계 진행 현황 조회 =====
export interface StepProgressItem {
  id: number;
  process_step_id: number;
  work_order_item_id: number | null;
  step_code: string;
  step_name: string;
  sort_order: number;
  needs_inspection: boolean;
  connection_type: string | null;
  completion_type: string | null;
  status: string;
  is_completed: boolean;
  completed_at: string | null;
  completed_by: number | null;
  work_order_status_changed?: boolean;
}

export async function getStepProgress(
  workOrderId: string
): Promise<{
  success: boolean;
  data: StepProgressItem[];
  error?: string;
}> {
  const result = await executeServerAction<StepProgressItem[]>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/step-progress`,
    errorMessage: '단계 진행 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  return { success: true, data: result.data };
}

// ===== 공정 단계 완료 토글 =====
export async function toggleStepProgress(
  workOrderId: string,
  progressId: number
): Promise<{ success: boolean; data?: StepProgressItem; error?: string }> {
  const result = await executeServerAction<StepProgressItem>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/step-progress/${progressId}/toggle`,
    method: 'PATCH',
    errorMessage: '단계 토글에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 작업지시 상세 조회 (items + options 포함) =====
export async function getWorkOrderDetail(
  workOrderId: string
): Promise<{
  success: boolean;
  data: WorkItemData[];
  error?: string;
}> {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const result = await executeServerAction<any>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}`,
    errorMessage: '작업지시 상세 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };

  const wo = result.data;
  const processName = (wo.process?.process_name || '').toLowerCase();
  const processType: ProcessTab =
    processName.includes('스크린') ? 'screen' :
    processName.includes('슬랫') ? 'slat' :
    processName.includes('절곡') ? 'bending' : 'screen';

  const items: WorkItemData[] = (wo.items || []).map((item: {
    id: number; item_name: string; specification: string | null;
    quantity: string; unit: string | null; status: string;
    sort_order: number; options: Record<string, unknown> | null;
  }, index: number) => {
    const opts = item.options || {};
    const stepProgressList = wo.step_progress || [];
    const processSteps = wo.process?.steps || [];

    let steps: WorkStepData[];
    if (stepProgressList.length > 0) {
      steps = stepProgressList
        .filter((sp: { work_order_item_id: number | null }) => !sp.work_order_item_id || sp.work_order_item_id === item.id)
        .map((sp: {
          id: number;
          process_step: {
            step_name: string; step_code: string;
            needs_inspection?: boolean; connection_type?: string; completion_type?: string;
          } | null;
          status: string;
        }) => ({
          id: String(sp.id),
          name: sp.process_step?.step_name || '',
          isMaterialInput: (sp.process_step?.step_code || '').includes('MAT') || (sp.process_step?.step_name || '').includes('자재투입'),
          isInspection: sp.process_step?.needs_inspection || false,
          isCompleted: sp.status === 'completed',
          stepProgressId: sp.id,
          needsInspection: sp.process_step?.needs_inspection || false,
          connectionType: sp.process_step?.connection_type || undefined,
          connectionTarget: undefined, // step_progress API에 미포함, processListCache에서 보완
          completionType: sp.process_step?.completion_type || undefined,
        }));
    } else {
      steps = processSteps.map((ps: {
        id: number; step_name: string; step_code: string;
        needs_inspection?: boolean; connection_type?: string; completion_type?: string;
      }, si: number) => ({
        id: `${item.id}-step-${si}`,
        name: ps.step_name,
        isMaterialInput: ps.step_code.includes('MAT') || ps.step_name.includes('자재투입'),
        isInspection: ps.needs_inspection || false,
        isCompleted: false,
        needsInspection: ps.needs_inspection || false,
        connectionType: ps.connection_type || undefined,
        completionType: ps.completion_type || undefined,
      }));
    }

    const workItem: WorkItemData = {
      id: String(item.id), itemNo: index + 1,
      itemCode: wo.work_order_no || '-', itemName: item.item_name || '-',
      floor: (opts.floor as string) || '-', code: (opts.code as string) || '-',
      width: (opts.width as number) || 0, height: (opts.height as number) || 0,
      quantity: Number(item.quantity) || 0, processType, steps, materialInputs: [],
    };

    if (opts.cutting_info) {
      const ci = opts.cutting_info as { width: number; sheets: number };
      workItem.cuttingInfo = { width: ci.width, sheets: ci.sheets };
    }
    if (opts.slat_info) {
      const si = opts.slat_info as { length: number; slat_count: number; joint_bar: number; glass_qty: number };
      workItem.slatInfo = { length: si.length, slatCount: si.slat_count, jointBar: si.joint_bar, glassQty: si.glass_qty || 0 };
    }
    if (opts.bending_info) {
      const bi = opts.bending_info as {
        common: { kind: string; type: string; length_quantities: { length: number; quantity: number }[] };
        detail_parts: { part_name: string; material: string; barcy_info: string }[];
      };
      workItem.bendingInfo = {
        common: { kind: bi.common.kind, type: bi.common.type, lengthQuantities: bi.common.length_quantities || [] },
        detailParts: (bi.detail_parts || []).map(dp => ({ partName: dp.part_name, material: dp.material, barcyInfo: dp.barcy_info })),
      };
    }
    if (opts.is_wip) {
      workItem.isWip = true;
      const wi = opts.wip_info as { specification: string; length_quantity: string } | undefined;
      if (wi) {
        workItem.wipInfo = { specification: wi.specification, lengthQuantity: wi.length_quantity };
      }
    }
    if (opts.is_joint_bar) {
      workItem.isJointBar = true;
      const jb = opts.slat_joint_bar_info as { specification: string; length: number; quantity: number } | undefined;
      if (jb) workItem.slatJointBarInfo = jb;
    }

    return workItem;
  });

  return { success: true, data: items };
}

// ===== 개소별 중간검사 데이터 저장 =====
export async function saveItemInspection(
  workOrderId: string,
  itemId: number,
  processType: string,
  inspectionData: Record<string, unknown>
): Promise<{ success: boolean; data?: Record<string, unknown>; error?: string }> {
  const result = await executeServerAction<Record<string, unknown>>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/items/${itemId}/inspection`,
    method: 'POST',
    body: { process_type: processType, inspection_data: inspectionData },
    errorMessage: '검사 데이터 저장에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 작업지시 전체 검사 데이터 조회 =====
export interface InspectionDataItem {
  item_id: number;
  item_name: string;
  specification: string | null;
  quantity: number;
  sort_order: number;
  options: Record<string, unknown> | null;
  inspection_data: Record<string, unknown>;
}

export async function getWorkOrderInspectionData(
  workOrderId: string
): Promise<{
  success: boolean;
  data?: { work_order_id: number; items: InspectionDataItem[]; total: number };
  error?: string;
}> {
  const result = await executeServerAction<{ work_order_id: number; items: InspectionDataItem[]; total: number }>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-data`,
    errorMessage: '검사 데이터 조회에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 작업일지 저장 =====
export async function saveWorkLog(
  workOrderId: string,
  data: {
    basic_data?: Record<string, string>;
    table_data?: Array<Record<string, unknown>>;
    remarks?: string;
    title?: string;
    rendered_html?: string;
  }
): Promise<{
  success: boolean;
  data?: { document_id: number; document_no: string; status: string };
  error?: string;
}> {
  const result = await executeServerAction<{ document_id: number; document_no: string; status: string }>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/work-log`,
    method: 'POST',
    body: data,
    errorMessage: '작업일지 저장에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 작업일지 조회 =====
export async function getWorkLog(
  workOrderId: string
): Promise<{
  success: boolean;
  data?: {
    template: Record<string, unknown>;
    document: Record<string, unknown> | null;
    auto_values: Record<string, string>;
    work_stats: Record<string, unknown>;
    bending_images: Record<string, string>;
  };
  error?: string;
}> {
  const result = await executeServerAction<{
    template: Record<string, unknown>;
    document: Record<string, unknown> | null;
    auto_values: Record<string, string>;
    work_stats: Record<string, unknown>;
    bending_images: Record<string, string>;
  }>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/work-log`,
    errorMessage: '작업일지 조회에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 검사 문서 템플릿 타입 (types.ts에서 import) =====
import type { InspectionTemplateData } from './types';

export async function getInspectionTemplate(
  workOrderId: string
): Promise<{
  success: boolean;
  data?: InspectionTemplateData;
  error?: string;
}> {
  const result = await executeServerAction<InspectionTemplateData>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-template`,
    errorMessage: '검사 템플릿 조회에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 검사 문서 동기화 (원본: work_order_items → document_data) =====
export async function saveInspectionDocument(
  workOrderId: string,
  data: {
    title?: string;
    approvers?: { role_name: string; user_id?: number }[];
  } = {}
): Promise<{
  success: boolean;
  data?: { document_id: number; document_no: string; status: string };
  error?: string;
}> {
  const result = await executeServerAction<{ document_id: number; document_no: string; status: string }>({
    url: `${API_URL}/api/v1/work-orders/${workOrderId}/inspection-document`,
    method: 'POST',
    body: data,
    errorMessage: '검사 문서 동기화에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 부서 목록 조회 (작업 정보용) =====
export interface DepartmentOption {
  id: number;
  name: string;
}

export async function getDepartments(): Promise<{
  success: boolean;
  data: DepartmentOption[];
  error?: string;
}> {
  interface DeptApiItem { id: number; name: string; parent_id?: number | null; [key: string]: unknown }
  const result = await executeServerAction<{ data: DeptApiItem[] } | DeptApiItem[]>({
    url: buildApiUrl('/api/v1/departments', { per_page: 100 }),
    errorMessage: '부서 목록 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  const list = Array.isArray(result.data) ? result.data : (result.data.data || []);
  return {
    success: true,
    data: list.map((d) => ({ id: d.id, name: d.name })),
  };
}

// ===== 부서별 사용자 목록 조회 =====
export interface DepartmentUser {
  id: number;
  name: string;
}

export async function getDepartmentUsers(departmentId: number): Promise<{
  success: boolean;
  data: DepartmentUser[];
  error?: string;
}> {
  interface UserApiItem { id: number; name: string; [key: string]: unknown }
  const result = await executeServerAction<{ data: UserApiItem[] } | UserApiItem[]>({
    url: buildApiUrl(`/api/v1/departments/${departmentId}/users`),
    errorMessage: '부서 사용자 목록 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  const list = Array.isArray(result.data) ? result.data : (result.data.data || []);
  return {
    success: true,
    data: list.map((u) => ({ id: u.id, name: u.name })),
  };
}

// ===== 자재 투입용 재고 검색 =====
export interface StockSearchResult {
  itemId: number;
  itemCode: string;
  itemName: string;
  stockQty: number;
  availableQty: number;
  lotCount: number;
  lots: Array<{ lotNo: string; availableQty: number; fifoOrder: number }>;
}

// ===== [개발전용] 입고 강제 생성 =====
export async function forceCreateReceiving(
  itemId: number,
  qty: number = 100
): Promise<{ success: boolean; data?: { receiving_number: string; lot_no: string; item_code: string; item_name: string; qty: number; available_qty: number }; error?: string }> {
  const result = await executeServerAction<{
    receiving_number: string; lot_no: string; item_code: string; item_name: string; qty: number; available_qty: number;
  }>({
    url: buildApiUrl('/api/v1/dev/force-receiving'),
    method: 'POST',
    body: { item_id: itemId, qty },
    errorMessage: '입고 강제 생성에 실패했습니다.',
  });
  return { success: result.success, data: result.data, error: result.error };
}

export async function searchStockByCode(
  search: string,
  itemType?: string
): Promise<{ success: boolean; data: StockSearchResult[]; error?: string }> {
  const result = await executeServerAction<{
    data: Array<{
      // Item 모델 필드 (stocks API는 Item 기준 조회)
      id: number;
      code: string;
      name: string;
      item_type: string;
      stock?: {
        id: number;
        stock_qty: number;
        available_qty: number;
        lot_count?: number;
        lots?: Array<{ lot_no: string; available_qty: number; fifo_order: number }>;
      };
      // 레거시 호환 (직접 필드)
      item_id?: number;
      item_code?: string;
      item_name?: string;
      stock_qty?: number;
      available_qty?: number;
      lot_count?: number;
      lots?: Array<{ lot_no: string; available_qty: number; fifo_order: number }>;
    }>;
  }>({
    url: buildApiUrl('/api/v1/stocks', { search, per_page: 10, with_lots: 'true', item_type: itemType }),
    errorMessage: '재고 검색에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  const items = Array.isArray(result.data) ? result.data : (result.data.data || []);
  return {
    success: true,
    data: items.map((s) => {
      // Item 모델 구조: { id, code, name, stock: { stock_qty, ... } }
      const stock = s.stock;
      const itemId = s.item_id ?? s.id;
      const itemCode = s.item_code ?? s.code;
      const itemName = s.item_name ?? s.name;
      const stockQty = s.stock_qty ?? stock?.stock_qty ?? 0;
      const availableQty = s.available_qty ?? stock?.available_qty ?? 0;
      const lotCount = s.lot_count ?? stock?.lot_count ?? 0;
      const lots = s.lots ?? stock?.lots ?? [];
      return {
        itemId,
        itemCode,
        itemName,
        stockQty,
        availableQty,
        lotCount,
        lots: lots.map((l: { lot_no: string; available_qty: number; fifo_order: number }) => ({
          lotNo: l.lot_no,
          availableQty: l.available_qty,
          fifoOrder: l.fifo_order,
        })),
      };
    }),
  };
}

// ===== 품목(items) 검색 (재고 없는 품목도 검색) =====
export interface ItemSearchResult {
  itemId: number;
  itemCode: string;
  itemName: string;
  itemType: string;
  unit: string;
}

export async function searchItems(
  search: string,
  itemType?: string
): Promise<{ success: boolean; data: ItemSearchResult[]; error?: string }> {
  const result = await executeServerAction<{
    data: Array<{ id: number; code: string; name: string; item_type: string; unit: string }>;
  }>({
    url: buildApiUrl('/api/v1/items', { search, per_page: 10, item_type: itemType }),
    errorMessage: '품목 검색에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, data: [], error: result.error };
  const items = Array.isArray(result.data) ? result.data : (result.data.data || []);
  return {
    success: true,
    data: items.map((i: { id: number; code: string; name: string; item_type: string; unit: string }) => ({
      itemId: i.id,
      itemCode: i.code,
      itemName: i.name,
      itemType: i.item_type,
      unit: i.unit,
    })),
  };
}