/**
 * 출고 관리 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/shipments - 목록 조회
 * - GET /api/v1/shipments/stats - 통계 조회
 * - GET /api/v1/shipments/stats-by-status - 상태별 통계 조회
 * - GET /api/v1/shipments/{id} - 상세 조회
 * - POST /api/v1/shipments - 등록
 * - PUT /api/v1/shipments/{id} - 수정
 * - PATCH /api/v1/shipments/{id}/status - 상태 변경
 * - DELETE /api/v1/shipments/{id} - 삭제
 * - GET /api/v1/shipments/options/lots - LOT 옵션 조회
 * - GET /api/v1/shipments/options/logistics - 물류사 옵션 조회
 * - GET /api/v1/shipments/options/vehicle-tonnage - 차량 톤수 옵션 조회
 */

'use server';


import { executeServerAction } from '@/lib/api/execute-server-action';
import { executePaginatedAction } from '@/lib/api/execute-paginated-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type {
  ShipmentItem,
  ShipmentDetail,
  ShipmentProduct,
  ShipmentStats,
  ShipmentStatusStats,
  ShipmentStatus,
  ShipmentPriority,
  DeliveryMethod,
  FreightCostType,
  ShipmentEditFormData,
  LogisticsOption,
  VehicleTonnageOption,
} from './types';

// ===== API 데이터 타입 =====

// 수주 연동 정보 (Order → Shipment)
interface OrderInfoApiData {
  order_id?: number;
  order_no?: string;
  order_status?: string;
  client_id?: number;
  customer_name?: string;
  site_name?: string;
  delivery_address?: string;
  delivery_address_detail?: string;
  contact?: string;
  receiver?: string;
  receiver_contact?: string;
  delivery_date?: string;
  delivery_method?: string;
  writer_id?: number;
  writer_name?: string;
}

interface ShipmentApiData {
  id: number;
  shipment_no: string;
  lot_no?: string;
  order_id?: number;
  scheduled_date: string;
  status: ShipmentStatus;
  priority: ShipmentPriority;
  delivery_method: DeliveryMethod;
  client_id?: number;
  customer_name?: string;
  site_name?: string;
  delivery_address?: string;
  receiver?: string;
  receiver_contact?: string;
  // 수주 연동 정보 (order_info accessor)
  order_info?: OrderInfoApiData;
  can_ship: boolean;
  deposit_confirmed: boolean;
  invoice_issued: boolean;
  customer_grade?: string;
  loading_manager?: string;
  loading_time?: string;
  loading_completed_at?: string;
  logistics_company?: string;
  vehicle_tonnage?: string;
  shipping_cost?: string | number;
  vehicle_no?: string;
  driver_name?: string;
  driver_contact?: string;
  expected_arrival?: string;
  confirmed_arrival?: string;
  remarks?: string;
  created_by?: number;
  updated_by?: number;
  creator?: { id: number; name: string };
  created_at?: string;
  updated_at?: string;
  items?: ShipmentItemApiData[];
  vehicle_dispatches?: Array<{
    id: number;
    seq: number;
    logistics_company?: string;
    arrival_datetime?: string;
    tonnage?: string;
    vehicle_no?: string;
    driver_contact?: string;
    remarks?: string;
  }>;
  status_label?: string;
  priority_label?: string;
  delivery_method_label?: string;
  total_quantity?: number;
  item_count?: number;
}

interface ShipmentItemApiData {
  id: number;
  shipment_id: number;
  seq: number;
  item_code?: string;
  item_name: string;
  floor_unit?: string;
  specification?: string;
  quantity: string | number;
  unit?: string;
  lot_no?: string;
  stock_lot_id?: number;
  product_name?: string;
  remarks?: string;
}

interface ShipmentApiStatsResponse {
  today_shipment_count: number;
  scheduled_count: number;
  shipping_count: number;
  urgent_count: number;
}

interface ShipmentApiStatsByStatusResponse {
  all: number;
  scheduled: number;
  ready: number;
  shipping: number;
  completed: number;
}

// ===== API → Frontend 변환 (목록용) =====
function transformApiToListItem(data: ShipmentApiData): ShipmentItem {
  return {
    id: String(data.id),
    shipmentNo: data.shipment_no,
    lotNo: data.lot_no || '',
    orderLotNo: data.order_info?.order_no || '',
    scheduledDate: data.scheduled_date,
    status: data.status,
    priority: data.priority,
    deliveryMethod: data.delivery_method,
    deliveryMethodLabel: data.delivery_method_label || data.delivery_method,
    // 발주처/배송 정보: order_info 우선 참조 (Order가 Single Source of Truth)
    customerName: data.order_info?.customer_name || data.customer_name || '',
    siteName: data.order_info?.site_name || data.site_name || '',
    manager: data.loading_manager,
    canShip: data.can_ship,
    depositConfirmed: data.deposit_confirmed,
    invoiceIssued: data.invoice_issued,
    deliveryTime: data.vehicle_dispatches?.[0]?.arrival_datetime || data.expected_arrival,
    // 수신/작성자/출고일 매핑 (order_info 우선 → 출하 직접 필드 fallback)
    receiver: data.order_info?.receiver || data.receiver || '',
    receiverAddress: data.order_info?.delivery_address || data.delivery_address || '',
    receiverCompany: data.order_info?.customer_name || data.customer_name || '',
    writer: data.order_info?.writer_name || data.creator?.name || '',
    shipmentDate: data.scheduled_date || '',
  };
}

// ===== API → Frontend 변환 (품목용) =====
function transformApiToProduct(data: ShipmentItemApiData): ShipmentProduct {
  return {
    id: String(data.id),
    no: data.seq,
    itemCode: data.item_code || '',
    itemName: data.item_name,
    floorUnit: data.floor_unit || '',
    specification: data.specification || '',
    quantity: parseFloat(String(data.quantity)) || 0,
    lotNo: data.lot_no || '',
  };
}

// ===== API → Frontend 변환 (상세용) =====
function transformApiToDetail(data: ShipmentApiData): ShipmentDetail {
  // items를 floor_unit 기준으로 productGroups 자동 그룹핑
  const rawItems = data.items || [];
  const items = rawItems.map(transformApiToProduct);
  const groupMap = new Map<string, { productName: string; productCode: string; parts: { product: ShipmentProduct; unit: string }[] }>();
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    const raw = rawItems[i];
    const key = item.floorUnit || `item-${item.id}`;
    if (!groupMap.has(key)) {
      groupMap.set(key, { productName: key, productCode: raw.product_name || '', parts: [] });
    }
    groupMap.get(key)!.parts.push({ product: item, unit: raw.unit || '' });
  }
  const productGroups = Array.from(groupMap.entries()).map(([key, g]) => ({
    id: key,
    productName: g.productName,
    specification: g.productCode,
    partCount: g.parts.length,
    parts: g.parts.map((p, i) => ({
      id: p.product.id,
      seq: i + 1,
      itemName: p.product.itemName,
      specification: p.product.specification,
      quantity: p.product.quantity,
      unit: p.unit,
    })),
  }));

  return {
    id: String(data.id),
    orderId: data.order_id ?? data.order_info?.order_id,
    shipmentNo: data.shipment_no,
    lotNo: data.lot_no || '',
    orderLotNo: data.order_info?.order_no || '',
    scheduledDate: data.scheduled_date,
    shipmentDate: (data as unknown as Record<string, unknown>).shipment_date as string | undefined,
    status: data.status,
    priority: data.priority,
    deliveryMethod: data.delivery_method,
    freightCost: (data as unknown as Record<string, unknown>).freight_cost as FreightCostType | undefined,
    freightCostLabel: (data as unknown as Record<string, unknown>).freight_cost_label as string | undefined,
    depositConfirmed: data.deposit_confirmed,
    invoiceIssued: data.invoice_issued,
    customerGrade: data.customer_grade || '',
    canShip: data.can_ship,
    loadingManager: data.loading_manager,
    loadingCompleted: data.loading_completed_at,
    registrant: data.creator?.name,
    // 발주처/배송 정보: order_info 우선 참조 (Order가 Single Source of Truth)
    customerName: data.order_info?.customer_name || data.customer_name || '',
    siteName: data.order_info?.site_name || data.site_name || '',
    deliveryAddress: data.order_info?.delivery_address || data.delivery_address || '',
    receiver: data.order_info?.receiver || data.receiver,
    receiverContact: data.order_info?.receiver_contact || data.order_info?.contact || data.receiver_contact,
    zipCode: (data as unknown as Record<string, unknown>).zip_code as string | undefined,
    address: (data as unknown as Record<string, unknown>).address as string | undefined,
    addressDetail: (data as unknown as Record<string, unknown>).address_detail as string | undefined,
    // 배차 정보 - vehicle_dispatches 테이블에서 조회, 없으면 레거시 단일 필드 fallback
    vehicleDispatches: data.vehicle_dispatches && data.vehicle_dispatches.length > 0
      ? data.vehicle_dispatches.map((vd) => ({
          id: String(vd.id),
          logisticsCompany: vd.logistics_company || '-',
          arrivalDateTime: vd.arrival_datetime || '-',
          tonnage: vd.tonnage || '-',
          vehicleNo: vd.vehicle_no || '-',
          driverContact: vd.driver_contact || '-',
          remarks: vd.remarks || '',
        }))
      : (data.vehicle_no || data.logistics_company || data.driver_contact
        ? [{
            id: `vd-legacy-${data.id}`,
            logisticsCompany: data.logistics_company || '-',
            arrivalDateTime: data.confirmed_arrival || data.expected_arrival || '-',
            tonnage: data.vehicle_tonnage || '-',
            vehicleNo: data.vehicle_no || '-',
            driverContact: data.driver_contact || '-',
            remarks: '',
          }]
        : []),
    // 제품내용 (그룹핑) - floor_unit 기준 자동 그룹핑
    productGroups,
    otherParts: [],
    products: items,
    logisticsCompany: data.logistics_company,
    vehicleTonnage: data.vehicle_tonnage,
    shippingCost: data.shipping_cost ? parseFloat(String(data.shipping_cost)) : undefined,
    vehicleNo: data.vehicle_no,
    driverName: data.driver_name,
    driverContact: data.driver_contact,
    remarks: data.remarks,
  };
}

// ===== API → Frontend 변환 (통계용) =====
function transformApiToStats(data: ShipmentApiStatsResponse & { total_count?: number; completed_count?: number; ready_count?: number }): ShipmentStats {
  return {
    todayShipmentCount: data.today_shipment_count,
    scheduledCount: data.scheduled_count,
    shippingCount: data.shipping_count,
    completedCount: data.completed_count || 0,
    urgentCount: data.urgent_count,
    totalCount: data.total_count || 0,
  };
}

// ===== API → Frontend 변환 (상태별 통계용) =====
const STATUS_TAB_LABELS: Record<string, string> = {
  all: '전체',
  scheduled: '출고예정',
  ready: '출고대기',
  shipping: '배송중',
  completed: '배송완료',
};

function transformApiToStatsByStatus(data: ShipmentApiStatsByStatusResponse): ShipmentStatusStats {
  const result: ShipmentStatusStats = {};
  for (const [key, count] of Object.entries(data)) {
    if (key !== 'all') { // all은 탭에서 제외 (전체 탭은 별도 처리)
      result[key] = {
        label: STATUS_TAB_LABELS[key] || key,
        count: count as number,
      };
    }
  }
  return result;
}

// ===== Frontend → API 변환 (수정용) =====
function transformEditFormToApi(
  data: Partial<ShipmentEditFormData>
): Record<string, unknown> {
  const result: Record<string, unknown> = {};

  if (data.scheduledDate !== undefined) result.scheduled_date = data.scheduledDate;
  if (data.priority !== undefined) result.priority = data.priority;
  if (data.deliveryMethod !== undefined) result.delivery_method = data.deliveryMethod;
  if (data.receiver !== undefined) result.receiver = data.receiver;
  if (data.receiverContact !== undefined) result.receiver_contact = data.receiverContact;
  // 주소: zipCode + address + addressDetail → delivery_address로 결합
  if (data.address !== undefined || data.zipCode !== undefined || data.addressDetail !== undefined) {
    const parts = [
      data.zipCode ? `[${data.zipCode}]` : '',
      data.address || '',
      data.addressDetail || '',
    ].filter(Boolean);
    result.delivery_address = parts.join(' ');
  }
  if (data.loadingManager !== undefined) result.loading_manager = data.loadingManager;
  if (data.logisticsCompany !== undefined) result.logistics_company = data.logisticsCompany;
  if (data.vehicleTonnage !== undefined) result.vehicle_tonnage = data.vehicleTonnage;
  if (data.vehicleNo !== undefined) result.vehicle_no = data.vehicleNo;
  if (data.shippingCost !== undefined) result.shipping_cost = data.shippingCost;
  if (data.driverName !== undefined) result.driver_name = data.driverName;
  if (data.driverContact !== undefined) result.driver_contact = data.driverContact;
  if (data.expectedArrival !== undefined) result.expected_arrival = data.expectedArrival;
  if (data.confirmedArrival !== undefined) result.confirmed_arrival = data.confirmedArrival;
  if (data.changeReason !== undefined) result.change_reason = data.changeReason;
  if (data.remarks !== undefined) result.remarks = data.remarks;

  if (data.vehicleDispatches) {
    result.vehicle_dispatches = data.vehicleDispatches.map((vd, idx) => ({
      seq: idx + 1,
      logistics_company: vd.logisticsCompany || null,
      arrival_datetime: vd.arrivalDateTime || null,
      tonnage: vd.tonnage || null,
      vehicle_no: vd.vehicleNo || null,
      driver_contact: vd.driverContact || null,
      remarks: vd.remarks || null,
    }));
  }

  return result;
}


// ===== 출고 목록 조회 =====
export async function getShipments(params?: {
  page?: number; perPage?: number; search?: string; status?: string;
  priority?: string; deliveryMethod?: string; scheduledFrom?: string; scheduledTo?: string;
  canShip?: boolean; depositConfirmed?: boolean; sortBy?: string; sortDir?: string;
}) {
  return executePaginatedAction<ShipmentApiData, ShipmentItem>({
    url: buildApiUrl('/api/v1/shipments', {
      page: params?.page,
      per_page: params?.perPage,
      search: params?.search,
      status: params?.status !== 'all' ? params?.status : undefined,
      priority: params?.priority !== 'all' ? params?.priority : undefined,
      delivery_method: params?.deliveryMethod !== 'all' ? params?.deliveryMethod : undefined,
      scheduled_from: params?.scheduledFrom,
      scheduled_to: params?.scheduledTo,
      can_ship: params?.canShip,
      deposit_confirmed: params?.depositConfirmed,
      sort_by: params?.sortBy,
      sort_dir: params?.sortDir,
    }),
    transform: transformApiToListItem,
    errorMessage: '출고 목록 조회에 실패했습니다.',
  });
}

// ===== 출고 통계 조회 =====
export async function getShipmentStats(): Promise<{ success: boolean; data?: ShipmentStats; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/shipments/stats'),
    transform: (data: ShipmentApiStatsResponse & { total_count?: number }) => transformApiToStats(data),
    errorMessage: '출고 통계 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 상태별 통계 조회 (탭용) =====
export async function getShipmentStatsByStatus(): Promise<{ success: boolean; data?: ShipmentStatusStats; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/shipments/stats-by-status'),
    transform: (data: ShipmentApiStatsByStatusResponse) => transformApiToStatsByStatus(data),
    errorMessage: '상태별 통계 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 출고 상세 조회 =====
export async function getShipmentById(id: string): Promise<{ success: boolean; data?: ShipmentDetail; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/shipments/${id}`),
    transform: (data: ShipmentApiData) => transformApiToDetail(data),
    errorMessage: '출고 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 출고 수정 =====
export async function updateShipment(
  id: string, data: Partial<ShipmentEditFormData>
): Promise<{ success: boolean; data?: ShipmentDetail; error?: string; __authError?: boolean }> {
  const apiData = transformEditFormToApi(data);
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/shipments/${id}`),
    method: 'PUT',
    body: apiData,
    transform: (d: ShipmentApiData) => transformApiToDetail(d),
    errorMessage: '출고 수정에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 출고 상태 변경 =====
export async function updateShipmentStatus(
  id: string, status: ShipmentStatus,
  additionalData?: {
    loadingTime?: string; loadingCompletedAt?: string; vehicleNo?: string;
    driverName?: string; driverContact?: string; confirmedArrival?: string;
  }
): Promise<{ success: boolean; data?: ShipmentDetail; error?: string; __authError?: boolean }> {
  const apiData: Record<string, unknown> = { status };
  if (additionalData?.loadingTime) apiData.loading_time = additionalData.loadingTime;
  if (additionalData?.loadingCompletedAt) apiData.loading_completed_at = additionalData.loadingCompletedAt;
  if (additionalData?.vehicleNo) apiData.vehicle_no = additionalData.vehicleNo;
  if (additionalData?.driverName) apiData.driver_name = additionalData.driverName;
  if (additionalData?.driverContact) apiData.driver_contact = additionalData.driverContact;
  if (additionalData?.confirmedArrival) apiData.confirmed_arrival = additionalData.confirmedArrival;

  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/shipments/${id}/status`),
    method: 'PATCH',
    body: apiData,
    transform: (d: ShipmentApiData) => transformApiToDetail(d),
    errorMessage: '상태 변경에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 물류사 옵션 조회 =====
export async function getLogisticsOptions(): Promise<{ success: boolean; data: LogisticsOption[]; error?: string; __authError?: boolean }> {
  const result = await executeServerAction<LogisticsOption[]>({
    url: buildApiUrl('/api/v1/shipments/options/logistics'),
    errorMessage: '물류사 옵션 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, data: [], __authError: true };
  return { success: result.success, data: result.data || [], error: result.error };
}

// ===== 차량 톤수 옵션 조회 =====
export async function getVehicleTonnageOptions(): Promise<{ success: boolean; data: VehicleTonnageOption[]; error?: string; __authError?: boolean }> {
  const result = await executeServerAction<VehicleTonnageOption[]>({
    url: buildApiUrl('/api/v1/shipments/options/vehicle-tonnage'),
    errorMessage: '차량 톤수 옵션 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, data: [], __authError: true };
  return { success: result.success, data: result.data || [], error: result.error };
}
