/**
 * 재고 현황 서버 액션
 *
 * API Endpoints (Item 기준):
 * - GET /api/v1/stocks - 목록 조회 (Item + Stock LEFT JOIN)
 * - GET /api/v1/stocks/stats - 통계 조회
 * - GET /api/v1/stocks/stats-by-type - 품목유형별 통계 조회
 * - GET /api/v1/stocks/{id} - 상세 조회 (Item 기준, LOT 포함)
 */

'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 {
  StockItem,
  StockDetail,
  StockStats,
  LotDetail,
  ItemType,
  StockStatusType,
  LotStatusType,
} from './types';

// ===== API 데이터 타입 (Item 기준) =====

// Stock 관계 데이터
interface StockRelationData {
  id: number;
  item_id: number;
  stock_qty: string | number;
  safety_stock: string | number;
  max_stock: string | number;
  reserved_qty: string | number;
  available_qty: string | number;
  lot_count: number;
  oldest_lot_date?: string;
  days_elapsed?: number;
  location?: string;
  status: StockStatusType;
  last_receipt_date?: string;
  last_issue_date?: string;
  lots?: StockLotApiData[];
}

// Item API 응답 데이터
interface ItemApiData {
  id: number;
  tenant_id: number;
  code: string;           // Item.code (기존 item_code)
  name: string;           // Item.name (기존 item_name)
  item_type: ItemType;    // Item.item_type (RM, SM, CS)
  unit: string;
  category_id?: number;
  category?: {
    id: number;
    name: string;
  };
  description?: string;
  attributes?: Record<string, unknown>;
  is_active: boolean;
  created_at?: string;
  updated_at?: string;
  stock?: StockRelationData | null;  // Stock 관계 (없으면 null)
}

interface StockLotApiData {
  id: number;
  stock_id: number;
  lot_no: string;
  fifo_order: number;
  receipt_date: string;
  days_elapsed?: number;
  qty: string | number;
  reserved_qty: string | number;
  available_qty: string | number;
  unit?: string;
  supplier?: string;
  supplier_lot?: string;
  po_number?: string;
  location?: string;
  status: LotStatusType;
  status_label?: string;
  created_at?: string;
  updated_at?: string;
}

interface StockApiStatsResponse {
  total_items: number;
  normal_count: number;
  low_count: number;
  out_count: number;
  no_stock_count: number;
}

interface StockApiStatsByTypeResponse {
  [key: string]: {
    label: string;
    count: number;
    total_qty: number | string;
  };
}

// ===== API → Frontend 변환 (목록용) =====
function transformApiToListItem(data: ItemApiData): StockItem {
  const stock = data.stock;
  const hasStock = !!stock;

  // 규격: attributes.spec → thickness/width/length 조합 → stock.specification
  let specification = '';
  if (data.attributes && typeof data.attributes === 'object') {
    const attrs = data.attributes as Record<string, unknown>;
    if (attrs.spec && String(attrs.spec).trim()) {
      specification = String(attrs.spec).trim();
    } else {
      const parts: string[] = [];
      if (attrs.thickness) parts.push(`${attrs.thickness}T`);
      if (attrs.width) parts.push(`${attrs.width}`);
      if (attrs.length) parts.push(`${attrs.length}`);
      if (parts.length > 0) specification = parts.join('×');
    }
  }
  if (!specification && hasStock) {
    const stockSpec = (stock as unknown as Record<string, unknown>).specification;
    if (stockSpec && String(stockSpec).trim()) specification = String(stockSpec).trim();
  }

  return {
    id: String(data.id),
    itemCode: data.code,
    itemName: data.name,
    itemType: data.item_type,
    specification,
    unit: data.unit || 'EA',
    calculatedQty: hasStock ? (parseFloat(String(stock.stock_qty)) || 0) : 0,
    actualQty: hasStock ? (parseFloat(String(stock.stock_qty)) || 0) : 0,
    stockQty: hasStock ? (parseFloat(String(stock.stock_qty)) || 0) : 0,
    safetyStock: hasStock ? (parseFloat(String(stock.safety_stock)) || 0) : 0,
    maxStock: hasStock ? (parseFloat(String(stock.max_stock)) || 0) : 0,
    wipQty: hasStock ? (parseFloat(String((stock as unknown as Record<string, unknown>).wip_qty)) || 0) : 0,
    lotCount: hasStock ? (stock.lot_count || 0) : 0,
    lotDaysElapsed: hasStock ? (stock.days_elapsed || 0) : 0,
    status: hasStock ? stock.status : null,
    lastTransactionDate: (() => {
      if (!hasStock) return '-';
      const receipt = stock.last_receipt_date || '';
      const issue = stock.last_issue_date || '';
      if (receipt && issue) return receipt > issue ? receipt : issue;
      return receipt || issue || '-';
    })(),
    useStatus: data.is_active === false ? 'inactive' : 'active',
    location: hasStock ? (stock.location || '-') : '-',
    hasStock,
  };
}

// ===== API → Frontend 변환 (LOT용) =====
function transformApiToLot(data: StockLotApiData): LotDetail {
  return {
    id: String(data.id),
    fifoOrder: data.fifo_order,
    lotNo: data.lot_no,
    receiptDate: data.receipt_date,
    daysElapsed: data.days_elapsed || 0,
    supplier: data.supplier || '-',
    poNumber: data.po_number || '-',
    qty: parseFloat(String(data.qty)) || 0,
    unit: data.unit || 'EA',
    location: data.location || '-',
    status: data.status,
  };
}

// ===== API → Frontend 변환 (상세용) =====
function transformApiToDetail(data: ItemApiData): StockDetail {
  const stock = data.stock;
  const hasStock = !!stock;

  // 규격: attributes.spec → thickness/width/length 조합 → stock.specification
  let specification = '-';
  if (data.attributes && typeof data.attributes === 'object') {
    const attrs = data.attributes as Record<string, unknown>;
    if (attrs.spec && String(attrs.spec).trim()) {
      specification = String(attrs.spec).trim();
    } else {
      const parts: string[] = [];
      if (attrs.thickness) parts.push(`${attrs.thickness}T`);
      if (attrs.width) parts.push(`${attrs.width}`);
      if (attrs.length) parts.push(`${attrs.length}`);
      if (parts.length > 0) specification = parts.join('×');
    }
  }
  if (specification === '-' && hasStock) {
    const stockSpec = (stock as unknown as Record<string, unknown>).specification;
    if (stockSpec && String(stockSpec).trim()) specification = String(stockSpec).trim();
  }

  return {
    id: String(data.id),
    itemCode: data.code,
    itemName: data.name,
    itemType: data.item_type,
    category: data.category?.name || '-',
    specification,
    unit: data.unit || 'EA',
    currentStock: hasStock ? (parseFloat(String(stock.stock_qty)) || 0) : 0,
    safetyStock: hasStock ? (parseFloat(String(stock.safety_stock)) || 0) : 0,
    maxStock: hasStock ? (parseFloat(String(stock.max_stock)) || 0) : 0,
    location: hasStock ? (stock.location || '-') : '-',
    lotCount: hasStock ? (stock.lot_count || 0) : 0,
    lastReceiptDate: hasStock ? (stock.last_receipt_date || '-') : '-',
    status: hasStock ? stock.status : null,
    hasStock,
    lots: hasStock && stock.lots ? stock.lots.map(transformApiToLot) : [],
  };
}

// ===== API → Frontend 변환 (통계용) =====
function transformApiToStats(data: StockApiStatsResponse): StockStats {
  return {
    totalItems: data.total_items,
    normalCount: data.normal_count,
    lowCount: data.low_count,
    outCount: data.out_count,
    noStockCount: data.no_stock_count || 0,
  };
}


// ===== 재고 목록 조회 =====
export async function getStocks(params?: {
  page?: number; perPage?: number; search?: string; itemType?: string;
  itemCategory?: string;
  status?: string; useStatus?: string; location?: string;
  sortBy?: string; sortDir?: string; startDate?: string; endDate?: string;
}) {
  return executePaginatedAction<ItemApiData, StockItem>({
    url: buildApiUrl('/api/v1/stocks', {
      page: params?.page,
      per_page: params?.perPage,
      search: params?.search,
      item_type: params?.itemType !== 'all' ? params?.itemType : undefined,
      item_category: params?.itemCategory !== 'all' ? params?.itemCategory : undefined,
      status: params?.status !== 'all' ? params?.status : undefined,
      is_active: params?.useStatus && params.useStatus !== 'all' ? (params.useStatus === 'active' ? '1' : '0') : undefined,
      location: params?.location,
      sort_by: params?.sortBy,
      sort_dir: params?.sortDir,
      start_date: params?.startDate,
      end_date: params?.endDate,
    }),
    transform: transformApiToListItem,
    errorMessage: '재고 목록 조회에 실패했습니다.',
  });
}

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

// ===== 품목유형별 통계 조회 =====
export async function getStockStatsByType(): Promise<{ success: boolean; data?: StockApiStatsByTypeResponse; error?: string; __authError?: boolean }> {
  const result = await executeServerAction<StockApiStatsByTypeResponse>({
    url: buildApiUrl('/api/v1/stocks/stats-by-type'),
    errorMessage: '품목유형별 통계 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 재고 상세 조회 (Item 기준, LOT 포함) =====
export async function getStockById(id: string): Promise<{ success: boolean; data?: StockDetail; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/stocks/${id}`),
    transform: (data: ItemApiData) => transformApiToDetail(data),
    errorMessage: '재고 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 재고 단건 수정 =====
export async function updateStock(
  id: string, data: { safetyStock: number; maxStock: number; useStatus: 'active' | 'inactive' }
): Promise<{ success: boolean; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/stocks/${id}`),
    method: 'PUT',
    body: {
      safety_stock: data.safetyStock,
      max_stock: data.maxStock,
      is_active: data.useStatus === 'active',
    },
    errorMessage: '재고 수정에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, error: result.error };
}

// ===== 재고 조정 이력 조회 =====
export interface StockAdjustmentRecord {
  id: number;
  adjusted_at: string;
  quantity: number;
  balance_qty: number;
  remark: string | null;
  inspector: string;
}

export async function getStockAdjustments(stockId: string): Promise<{ success: boolean; data?: StockAdjustmentRecord[]; error?: string; __authError?: boolean }> {
  const result = await executeServerAction<{ data: StockAdjustmentRecord[] }, StockAdjustmentRecord[]>({
    url: buildApiUrl(`/api/v1/stocks/${stockId}/adjustments`),
    transform: (d) => d.data || [],
    errorMessage: '재고 조정 이력 조회에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ===== 재고 조정 등록 =====
export async function createStockAdjustment(
  stockId: string,
  data: { quantity: number; remark?: string }
): Promise<{ success: boolean; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl(`/api/v1/stocks/${stockId}/adjustments`),
    method: 'POST',
    body: data,
    errorMessage: '재고 조정 등록에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, error: result.error };
}

// ===== 재고 실사 (일괄 업데이트) =====
export async function updateStockAudit(updates: { id: string; actualQty: number }[]): Promise<{ success: boolean; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/stocks/audit'),
    method: 'POST',
    body: { items: updates.map((u) => ({ item_id: u.id, actual_qty: u.actualQty })) },
    errorMessage: '재고 실사 저장에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, error: result.error };
}

// ===== 사용현황(거래이력) 조회 =====
export interface StockTransaction {
  id: number;
  type: string;
  typeLabel: string;
  qty: number;
  balanceQty: number;
  referenceType: string;
  referenceId: number;
  referenceNo: string | null;
  lotNo: string;
  reason: string | null;
  remark: string | null;
  itemCode: string;
  itemName: string;
  createdAt: string;
}

export interface StockUsageData {
  itemCode: string;
  itemName: string;
  currentQty: number;
  availableQty: number;
  transactions: StockTransaction[];
}

export async function getStockTransactions(
  itemId: string
): Promise<{ success: boolean; data?: StockUsageData; error?: string }> {
  const result = await executeServerAction<{
    item_code: string; item_name: string; current_qty: number; available_qty: number;
    transactions: Array<{
      id: number; type: string; type_label: string; qty: number; balance_qty: number;
      reference_type: string; reference_id: number; reference_no: string | null;
      lot_no: string; reason: string | null; remark: string | null;
      item_code: string; item_name: string; created_at: string;
    }>;
  }>({
    url: buildApiUrl(`/api/v1/stocks/${itemId}/transactions`),
    errorMessage: '사용현황 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return { success: false, error: result.error };
  return {
    success: true,
    data: {
      itemCode: result.data.item_code,
      itemName: result.data.item_name,
      currentQty: result.data.current_qty,
      availableQty: result.data.available_qty,
      transactions: result.data.transactions.map((t: { id: number; type: string; type_label: string; qty: number; balance_qty: number; reference_type: string; reference_id: number; reference_no: string | null; lot_no: string; reason: string | null; remark: string | null; item_code: string; item_name: string; created_at: string }) => ({
        id: t.id, type: t.type, typeLabel: t.type_label, qty: t.qty, balanceQty: t.balance_qty,
        referenceType: t.reference_type, referenceId: t.reference_id, referenceNo: t.reference_no,
        lotNo: t.lot_no, reason: t.reason, remark: t.remark,
        itemCode: t.item_code, itemName: t.item_name, createdAt: t.created_at,
      })),
    },
  };
}
