/**
 * 단가관리 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/pricing - 목록 조회
 * - GET /api/v1/pricing/{id} - 상세 조회
 * - POST /api/v1/pricing - 등록
 * - PUT /api/v1/pricing/{id} - 수정
 * - DELETE /api/v1/pricing/{id} - 삭제
 * - POST /api/v1/pricing/{id}/finalize - 확정
 * - GET /api/v1/pricing/{id}/revisions - 이력 조회
 */

'use server';


import { executeServerAction } from '@/lib/api/execute-server-action';
import type { PricingData, ItemInfo } from './types';

// API 응답 타입
interface _ApiResponse<T> {
  success: boolean;
  data: T;
  message: string;
}

// 단가 API 응답 데이터 타입
interface PriceApiData {
  id: number;
  tenant_id: number;
  item_type_code: string; // FG, PT, SM, RM, CS (items.item_type과 동일)
  item_id: number;
  client_group_id: number | null;
  purchase_price: string | null;
  processing_cost: string | null;
  loss_rate: string | null;
  margin_rate: string | null;
  sales_price: string | null;
  rounding_rule: 'round' | 'ceil' | 'floor';
  rounding_unit: number;
  supplier: string | null;
  effective_from: string;
  effective_to: string | null;
  status: 'draft' | 'active' | 'finalized';
  is_final: boolean;
  finalized_at: string | null;
  finalized_by: number | null;
  note: string | null;
  created_at: string;
  updated_at: string;
  deleted_at: string | null;
  client_group?: {
    id: number;
    name: string;
  };
  product?: {
    id: number;
    product_code: string;
    product_name: string;
    specification: string | null;
    unit: string;
    product_type: string;
  };
  material?: {
    id: number;
    item_code: string;
    item_name: string;
    specification: string | null;
    unit: string;
    product_type: string;
  };
  revisions?: Array<{
    id: number;
    revision_number: number;
    changed_at: string;
    changed_by: number;
    change_reason: string | null;
    before_snapshot: Record<string, unknown> | null;
    after_snapshot: Record<string, unknown>;
    changed_by_user?: {
      id: number;
      name: string;
    };
  }>;
}

/**
 * API 데이터 → 프론트엔드 타입 변환
 */
function transformApiToFrontend(apiData: PriceApiData): PricingData {
  const item = (apiData as unknown as Record<string, unknown>).item as Record<string, unknown> | undefined;
  const product = apiData.product;
  const material = apiData.material;

  const itemCode = (item?.code as string) || product?.product_code || material?.item_code || `ITEM-${apiData.item_id}`;
  const itemName = (item?.name as string) || product?.product_name || material?.item_name || '품목명 없음';
  const specification = product?.specification || material?.specification || undefined;
  const unit = product?.unit || material?.unit || 'EA';
  const itemType = (item?.item_category as string) || product?.product_type || material?.product_type || 'PT';

  // 리비전 변환
  const revisions = apiData.revisions?.map((rev) => ({
    revisionNumber: rev.revision_number,
    revisionDate: rev.changed_at,
    revisionBy: rev.changed_by_user?.name || `User ${rev.changed_by}`,
    revisionReason: rev.change_reason || undefined,
    previousData: rev.before_snapshot as unknown as PricingData,
  })) || [];

  return {
    id: String(apiData.id),
    itemId: String(apiData.item_id),
    itemCode,
    itemName,
    itemType,
    specification,
    unit,
    effectiveDate: apiData.effective_from,
    purchasePrice: apiData.purchase_price ? parseFloat(apiData.purchase_price) : undefined,
    processingCost: apiData.processing_cost ? parseFloat(apiData.processing_cost) : undefined,
    loss: apiData.loss_rate ? parseFloat(apiData.loss_rate) : undefined,
    roundingRule: apiData.rounding_rule || 'round',
    roundingUnit: apiData.rounding_unit || 1,
    marginRate: apiData.margin_rate ? parseFloat(apiData.margin_rate) : undefined,
    salesPrice: apiData.sales_price ? parseFloat(apiData.sales_price) : undefined,
    supplier: apiData.supplier || undefined,
    note: apiData.note || undefined,
    currentRevision: revisions.length,
    isFinal: apiData.is_final,
    revisions,
    finalizedDate: apiData.finalized_at || undefined,
    status: apiData.status,
    createdAt: apiData.created_at,
    createdBy: '관리자',
    updatedAt: apiData.updated_at,
    updatedBy: '관리자',
  };
}

/**
 * 프론트엔드 데이터 → API 요청 형식 변환
 * item_type_code는 품목 정보(data.itemType)에서 가져옴 (FG, PT, SM, RM, CS 등)
 */
function transformFrontendToApi(data: PricingData): Record<string, unknown> {
  return {
    item_type_code: data.itemType, // 품목에서 가져온 실제 item_type 값 사용
    item_id: parseInt(data.itemId),
    purchase_price: data.purchasePrice || null,
    processing_cost: data.processingCost || null,
    loss_rate: data.loss || null,
    margin_rate: data.marginRate || null,
    sales_price: data.salesPrice || null,
    rounding_rule: data.roundingRule || 'round',
    rounding_unit: data.roundingUnit || 1,
    supplier: data.supplier || null,
    effective_from: data.effectiveDate,
    effective_to: null,
    note: data.note || null,
    status: data.status || 'draft',
  };
}

const API_URL = process.env.NEXT_PUBLIC_API_URL;

export async function getPricingById(id: string): Promise<PricingData | null> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/pricing/${id}`,
    transform: (data: PriceApiData) => transformApiToFrontend(data),
    errorMessage: '단가 조회에 실패했습니다.',
  });
  return result.success ? result.data || null : null;
}

export async function getItemInfo(itemId: string): Promise<ItemInfo | null> {
  interface ItemApiItem { id: number; item_code: string; code?: string; name: string; item_type: string; specification?: string; unit?: string }
  const result = await executeServerAction<ItemApiItem>({
    url: `${API_URL}/api/v1/items/${itemId}`,
    errorMessage: '품목 조회에 실패했습니다.',
  });
  if (!result.success || !result.data) return null;
  const item = result.data;
  return {
    id: String(item.id), itemCode: item.item_code || item.code || '', itemName: item.name,
    itemType: item.item_type || 'PT', specification: item.specification || undefined, unit: item.unit || 'EA',
  };
}

export async function createPricing(
  data: PricingData
): Promise<{ success: boolean; data?: PricingData; error?: string; __authError?: boolean }> {
  const apiData = transformFrontendToApi(data);
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/pricing`,
    method: 'POST',
    body: apiData,
    transform: (d: PriceApiData) => transformApiToFrontend(d),
    errorMessage: '단가 등록에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

export async function updatePricing(
  id: string, data: PricingData, changeReason?: string
): Promise<{ success: boolean; data?: PricingData; error?: string; __authError?: boolean }> {
  const apiData = { ...transformFrontendToApi(data), change_reason: changeReason || null };
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/pricing/${id}`,
    method: 'PUT',
    body: apiData,
    transform: (d: PriceApiData) => transformApiToFrontend(d),
    errorMessage: '단가 수정에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

export async function deletePricing(id: string): Promise<{ success: boolean; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/pricing/${id}`,
    method: 'DELETE',
    errorMessage: '단가 삭제에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, error: result.error };
}

export async function finalizePricing(id: string): Promise<{ success: boolean; data?: PricingData; error?: string; __authError?: boolean }> {
  const result = await executeServerAction({
    url: `${API_URL}/api/v1/pricing/${id}/finalize`,
    method: 'POST',
    transform: (d: PriceApiData) => transformApiToFrontend(d),
    errorMessage: '단가 확정에 실패했습니다.',
  });
  if (result.__authError) return { success: false, __authError: true };
  return { success: result.success, data: result.data, error: result.error };
}

// ============================================
// 품목 목록 + 단가 목록 병합 조회
// ============================================

// 품목 API 응답 타입 (GET /api/v1/items)
interface ItemApiData {
  id: number;
  item_type: string; // FG, PT, SM, RM, CS (품목 유형)
  item_code?: string;
  code?: string;
  name: string;
  specification?: string;
  unit: string;
  category_id: number | null;
  attributes?: {
    salesPrice?: number;
    purchasePrice?: number;
    [key: string]: unknown;
  } | null;
  created_at: string;
  deleted_at: string | null;
}

// 단가 목록 조회용 타입
interface PriceApiListItem {
  id: number;
  tenant_id: number;
  item_type_code: string;
  item_id: number;
  client_group_id: number | null;
  purchase_price: string | null;
  processing_cost: string | null;
  loss_rate: string | null;
  margin_rate: string | null;
  sales_price: string | null;
  rounding_rule: 'round' | 'ceil' | 'floor';
  rounding_unit: number;
  supplier: string | null;
  effective_from: string;
  effective_to: string | null;
  status: 'draft' | 'active' | 'finalized';
  is_final: boolean;
  finalized_at: string | null;
  finalized_by: number | null;
  note: string | null;
  created_at: string;
  updated_at: string;
  deleted_at: string | null;
}

// 목록 표시용 타입
export interface PricingListItem {
  id: string;
  itemId: string;
  itemCode: string;
  itemName: string;
  itemType: string;
  specification?: string;
  unit: string;
  purchasePrice?: number;
  processingCost?: number;
  salesPrice?: number;
  marginRate?: number;
  effectiveDate?: string;
  status: 'draft' | 'active' | 'finalized' | 'not_registered';
  currentRevision: number;
  isFinal: boolean;
  itemTypeCode: string;
}

// 품목 유형 매핑 (type_code → 프론트엔드 ItemType)
function mapItemTypeForList(typeCode?: string): string {
  switch (typeCode) {
    case 'FG': return 'FG';
    case 'PT': return 'PT';
    case 'SM': return 'SM';
    case 'RM': return 'RM';
    case 'CS': return 'CS';
    default: return 'PT';
  }
}

// API 상태 → 프론트엔드 상태 매핑
function mapStatusForList(apiStatus: string, isFinal: boolean): 'draft' | 'active' | 'finalized' | 'not_registered' {
  if (isFinal) return 'finalized';
  switch (apiStatus) {
    case 'draft': return 'draft';
    case 'active': return 'active';
    case 'finalized': return 'finalized';
    default: return 'draft';
  }
}

/**
 * 단가 목록 데이터 조회 (품목 + 단가 병합)
 */
export async function getPricingListData(): Promise<PricingListItem[]> {
  interface ItemsPaginatedResponse { data: ItemApiData[]; current_page: number; last_page: number; per_page: number; total: number }
  interface PricingPaginatedResponse { data: PriceApiListItem[]; current_page: number; last_page: number; per_page: number; total: number }

  const [itemsResult, pricingResult] = await Promise.all([
    executeServerAction<ItemsPaginatedResponse>({
      url: `${API_URL}/api/v1/items?group_id=1&size=10000`,
      errorMessage: '품목 목록 조회에 실패했습니다.',
    }),
    executeServerAction<PricingPaginatedResponse>({
      url: `${API_URL}/api/v1/pricing?size=10000`,
      errorMessage: '단가 목록 조회에 실패했습니다.',
    }),
  ]);

  const items: ItemApiData[] = itemsResult.success ? (itemsResult.data?.data || []) : [];
  const pricings: PriceApiListItem[] = pricingResult.success ? (pricingResult.data?.data || []) : [];

  if (items.length === 0) return [];

  const pricingMap = new Map<string, PriceApiListItem>();
  for (const pricing of pricings) {
    const key = `${pricing.item_type_code}_${pricing.item_id}`;
    if (!pricingMap.has(key)) pricingMap.set(key, pricing);
  }

  return items.map((item) => {
    const key = `${item.item_type}_${item.id}`;
    const pricing = pricingMap.get(key);

    const itemCode = item.item_code || item.code || '';
    const specification = item.specification || undefined;

    if (pricing) {
      return {
        id: String(pricing.id), itemId: String(item.id), itemCode, itemName: item.name,
        itemType: mapItemTypeForList(item.item_type), specification, unit: item.unit || 'EA',
        purchasePrice: pricing.purchase_price ? parseFloat(pricing.purchase_price) : undefined,
        processingCost: pricing.processing_cost ? parseFloat(pricing.processing_cost) : undefined,
        salesPrice: pricing.sales_price ? parseFloat(pricing.sales_price) : undefined,
        marginRate: pricing.margin_rate ? parseFloat(pricing.margin_rate) : undefined,
        effectiveDate: pricing.effective_from,
        status: mapStatusForList(pricing.status, pricing.is_final),
        currentRevision: 0, isFinal: pricing.is_final, itemTypeCode: item.item_type,
      };
    } else {
      // prices 미등록 → items.attributes에서 참고 단가 표시
      const attrSalesPrice = item.attributes?.salesPrice ? Number(item.attributes.salesPrice) : undefined;
      const attrPurchasePrice = item.attributes?.purchasePrice ? Number(item.attributes.purchasePrice) : undefined;

      return {
        id: `item_${item.id}`, itemId: String(item.id), itemCode, itemName: item.name,
        itemType: mapItemTypeForList(item.item_type), specification, unit: item.unit || 'EA',
        purchasePrice: attrPurchasePrice, processingCost: undefined,
        salesPrice: attrSalesPrice, marginRate: undefined,
        effectiveDate: undefined, status: 'not_registered' as const,
        currentRevision: 0, isFinal: false, itemTypeCode: item.item_type,
      };
    }
  });
}

/**
 * 단가 이력 조회
 */
export async function getPricingRevisions(priceId: string): Promise<{
  success: boolean;
  data?: Array<{
    revisionNumber: number; revisionDate: string; revisionBy: string; revisionReason?: string;
    beforeSnapshot: Record<string, unknown> | null; afterSnapshot: Record<string, unknown>;
  }>;
  error?: string; __authError?: boolean;
}> {
  interface RevisionApiData {
    data?: Array<{
      revision_number: number; changed_at: string; changed_by: number;
      change_reason: string | null; before_snapshot: Record<string, unknown> | null;
      after_snapshot: Record<string, unknown>; changed_by_user?: { name: string };
    }>;
  }

  const result = await executeServerAction<RevisionApiData>({
    url: `${API_URL}/api/v1/pricing/${priceId}/revisions`,
    errorMessage: '이력 조회에 실패했습니다.',
  });

  if (result.__authError) return { success: false, __authError: true };
  if (!result.success || !result.data) return { success: false, error: result.error };

  const revisions = (result.data.data || []).map((rev) => ({
    revisionNumber: rev.revision_number,
    revisionDate: rev.changed_at,
    revisionBy: rev.changed_by_user?.name || `User ${rev.changed_by}`,
    revisionReason: rev.change_reason || undefined,
    beforeSnapshot: rev.before_snapshot,
    afterSnapshot: rev.after_snapshot,
  }));

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