/**
 * 매입 관리 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/purchases - 목록 조회
 * - GET /api/v1/purchases/{id} - 상세 조회
 * - POST /api/v1/purchases - 등록
 * - PUT /api/v1/purchases/{id} - 수정
 * - DELETE /api/v1/purchases/{id} - 삭제
 * - PUT /api/v1/purchases/{id}/confirm - 확정
 */

'use server';


import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
import type { PurchaseRecord, PurchaseType } from './types';

// ===== API 데이터 타입 =====
interface PurchaseApiData {
  id: number;
  purchase_number: string;
  purchase_date: string;
  client_id: number;
  client?: { id: number; name: string };
  supply_amount: string;
  tax_amount: string;
  total_amount: string;
  description?: string;
  status: string;
  purchase_type?: string;
  withdrawal_id?: number;
  approval_id?: number;
  approval?: {
    id: number;
    document_number: string;
    title: string;
    content?: Record<string, unknown>;
    form?: {
      id: number;
      name: string;
      category: string;
    };
  };
  tax_invoice_received: boolean;
  created_at?: string;
  updated_at?: string;
}

interface PurchaseApiPaginatedResponse {
  data: PurchaseApiData[];
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

// ===== API → Frontend 변환 =====

// 유효한 purchaseType 값 검증
const VALID_PURCHASE_TYPES: PurchaseType[] = [
  'unset', 'raw_material', 'subsidiary_material', 'product', 'outsourcing',
  'consumables', 'repair', 'transportation', 'office_supplies', 'rent',
  'utilities', 'communication', 'vehicle', 'entertainment', 'insurance', 'other_service'
];

function transformApiToFrontend(data: PurchaseApiData): PurchaseRecord {
  // purchase_type 변환 (API 값이 유효한지 검증)
  const purchaseType: PurchaseType =
    data.purchase_type && VALID_PURCHASE_TYPES.includes(data.purchase_type as PurchaseType)
      ? (data.purchase_type as PurchaseType)
      : 'unset';

  // 품의서/지출결의서 연결 정보 변환
  let sourceDocument: PurchaseRecord['sourceDocument'] = undefined;
  if (data.approval) {
    // form.category로 문서 유형 결정 (proposal=품의서, expense_report=지출결의서)
    const docType = data.approval.form?.category === 'expense_report' ? 'expense_report' : 'proposal';
    // content에서 예상금액 추출 (품의서 양식에 따라 다를 수 있음)
    const expectedCost = (data.approval.content?.expected_cost as number) ||
                         (data.approval.content?.total_amount as number) || 0;

    sourceDocument = {
      type: docType,
      documentNo: data.approval.document_number,
      title: data.approval.title,
      expectedCost,
    };
  }

  return {
    id: String(data.id),
    purchaseNo: data.purchase_number,
    purchaseDate: data.purchase_date,
    vendorId: String(data.client_id),
    vendorName: data.client?.name || '',
    supplyAmount: parseFloat(data.supply_amount) || 0,
    vat: parseFloat(data.tax_amount) || 0,
    totalAmount: parseFloat(data.total_amount) || 0,
    purchaseType,
    evidenceType: 'tax_invoice',
    status: data.status === 'confirmed' ? 'completed' : 'pending',
    approvalId: data.approval_id ? String(data.approval_id) : undefined,
    sourceDocument,
    items: [],
    taxInvoiceReceived: data.tax_invoice_received ?? false,
    createdAt: data.created_at || '',
    updatedAt: data.updated_at || '',
  };
}

// ===== Frontend → API 변환 =====
function transformFrontendToApi(data: Partial<PurchaseRecord>): Record<string, unknown> {
  const result: Record<string, unknown> = {};

  if (data.purchaseDate !== undefined) result.purchase_date = data.purchaseDate;
  if (data.vendorId !== undefined) result.client_id = parseInt(data.vendorId, 10);
  if (data.supplyAmount !== undefined) result.supply_amount = data.supplyAmount;
  if (data.vat !== undefined) result.tax_amount = data.vat;
  if (data.totalAmount !== undefined) result.total_amount = data.totalAmount;
  if (data.purchaseType !== undefined) result.purchase_type = data.purchaseType;
  if (data.taxInvoiceReceived !== undefined) result.tax_invoice_received = data.taxInvoiceReceived;
  if (data.approvalId !== undefined) result.approval_id = data.approvalId ? parseInt(data.approvalId, 10) : null;

  return result;
}

// ===== 페이지네이션 타입 =====
interface PaginationMeta {
  currentPage: number;
  lastPage: number;
  perPage: number;
  total: number;
}

// ===== 매입 목록 조회 =====
export async function getPurchases(params?: {
  page?: number;
  perPage?: number;
  startDate?: string;
  endDate?: string;
  clientId?: string;
  status?: string;
  search?: string;
}): Promise<{
  success: boolean;
  data: PurchaseRecord[];
  pagination: PaginationMeta;
  error?: string;
}> {
  const searchParams = new URLSearchParams();

  if (params?.page) searchParams.set('page', String(params.page));
  if (params?.perPage) searchParams.set('per_page', String(params.perPage));
  if (params?.startDate) searchParams.set('start_date', params.startDate);
  if (params?.endDate) searchParams.set('end_date', params.endDate);
  if (params?.clientId) searchParams.set('client_id', params.clientId);
  if (params?.status && params.status !== 'all') {
    searchParams.set('status', params.status);
  }
  if (params?.search) searchParams.set('search', params.search);

  const queryString = searchParams.toString();
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases${queryString ? `?${queryString}` : ''}`;

  console.log('[PurchaseActions] GET purchases:', url);

  const { response, error } = await serverFetch(url, { method: 'GET' });

  if (error) {
    return {
      success: false,
      data: [],
      pagination: { currentPage: 1, lastPage: 1, perPage: 20, total: 0 },
      error: error.message,
    };
  }

  if (!response?.ok) {
    console.warn('[PurchaseActions] GET purchases error:', response?.status);
    return {
      success: false,
      data: [],
      pagination: { currentPage: 1, lastPage: 1, perPage: 20, total: 0 },
      error: `API 오류: ${response?.status}`,
    };
  }

  const result = await response.json();

  if (!result.success) {
    return {
      success: false,
      data: [],
      pagination: { currentPage: 1, lastPage: 1, perPage: 20, total: 0 },
      error: result.message || '매입 목록 조회에 실패했습니다.',
    };
  }

  const paginatedData: PurchaseApiPaginatedResponse = result.data || {
    data: [],
    current_page: 1,
    last_page: 1,
    per_page: 20,
    total: 0,
  };

  const purchases = (paginatedData.data || []).map(transformApiToFrontend);

  return {
    success: true,
    data: purchases,
    pagination: {
      currentPage: paginatedData.current_page,
      lastPage: paginatedData.last_page,
      perPage: paginatedData.per_page,
      total: paginatedData.total,
    },
  };
}

// ===== 매입 상세 조회 =====
export async function getPurchaseById(id: string): Promise<{
  success: boolean;
  data?: PurchaseRecord;
  error?: string;
}> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases/${id}`;
  const { response, error } = await serverFetch(url, { method: 'GET' });

  if (error) {
    return { success: false, error: error.message };
  }

  if (!response?.ok) {
    console.error('[PurchaseActions] GET purchase error:', response?.status);
    return { success: false, error: `API 오류: ${response?.status}` };
  }

  const result = await response.json();

  if (!result.success || !result.data) {
    return { success: false, error: result.message || '매입 조회에 실패했습니다.' };
  }

  return { success: true, data: transformApiToFrontend(result.data) };
}

// ===== 매입 등록 =====
export async function createPurchase(
  data: Partial<PurchaseRecord>
): Promise<{ success: boolean; data?: PurchaseRecord; error?: string }> {
  const apiData = transformFrontendToApi(data);
  console.log('[PurchaseActions] POST purchase request:', apiData);

  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases`;
  const { response, error } = await serverFetch(url, {
    method: 'POST',
    body: JSON.stringify(apiData),
  });

  if (error) {
    return { success: false, error: error.message };
  }

  const result = await response?.json();
  console.log('[PurchaseActions] POST purchase response:', result);

  if (!response?.ok || !result.success) {
    return { success: false, error: result?.message || '매입 등록에 실패했습니다.' };
  }

  return { success: true, data: transformApiToFrontend(result.data) };
}

// ===== 매입 수정 =====
export async function updatePurchase(
  id: string,
  data: Partial<PurchaseRecord>
): Promise<{ success: boolean; data?: PurchaseRecord; error?: string }> {
  const apiData = transformFrontendToApi(data);
  console.log('[PurchaseActions] PUT purchase request:', apiData);

  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases/${id}`;
  const { response, error } = await serverFetch(url, {
    method: 'PUT',
    body: JSON.stringify(apiData),
  });

  if (error) {
    return { success: false, error: error.message };
  }

  const result = await response?.json();
  console.log('[PurchaseActions] PUT purchase response:', result);

  if (!response?.ok || !result.success) {
    return { success: false, error: result?.message || '매입 수정에 실패했습니다.' };
  }

  return { success: true, data: transformApiToFrontend(result.data) };
}

// ===== 세금계산서 수취 상태 토글 =====
export async function togglePurchaseTaxInvoice(
  id: string,
  value: boolean
): Promise<{ success: boolean; data?: PurchaseRecord; error?: string }> {
  try {
    return await updatePurchase(id, { taxInvoiceReceived: value });
  } catch (error) {
    // 인증 만료 등으로 인한 리다이렉트 에러 → 페이지 이동 없이 에러 반환
    if (isNextRedirectError(error)) {
      return { success: false, error: '세션이 만료되었습니다. 다시 로그인해주세요.' };
    }
    throw error;
  }
}

// ===== 매입 삭제 =====
export async function deletePurchase(id: string): Promise<{ success: boolean; error?: string }> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases/${id}`;
  const { response, error } = await serverFetch(url, { method: 'DELETE' });

  if (error) {
    return { success: false, error: error.message };
  }

  const result = await response?.json();
  console.log('[PurchaseActions] DELETE purchase response:', result);

  if (!response?.ok || !result.success) {
    return { success: false, error: result?.message || '매입 삭제에 실패했습니다.' };
  }

  return { success: true };
}

// ===== 매입 확정 =====
export async function confirmPurchase(id: string): Promise<{
  success: boolean;
  data?: PurchaseRecord;
  error?: string;
}> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/purchases/${id}/confirm`;
  const { response, error } = await serverFetch(url, { method: 'PUT' });

  if (error) {
    return { success: false, error: error.message };
  }

  const result = await response?.json();
  console.log('[PurchaseActions] PUT confirm response:', result);

  if (!response?.ok || !result.success) {
    return { success: false, error: result?.message || '매입 확정에 실패했습니다.' };
  }

  return { success: true, data: transformApiToFrontend(result.data) };
}

// ===== 은행 계좌 목록 조회 =====
export async function getBankAccounts(): Promise<{
  success: boolean;
  data: { id: string; bankName: string; accountName: string; accountNumber: string }[];
  error?: string;
}> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bank-accounts?per_page=100`;
  const { response, error } = await serverFetch(url, { method: 'GET' });

  if (error) {
    return { success: false, data: [], error: error.message };
  }

  if (!response?.ok) {
    return { success: false, data: [], error: `API 오류: ${response?.status}` };
  }

  const result = await response.json();

  if (!result.success) {
    return { success: false, data: [], error: result.message };
  }

  const accounts = result.data?.data || result.data || [];

  return {
    success: true,
    data: accounts.map((a: { id: number; bank_name: string; account_name: string; account_number: string }) => ({
      id: String(a.id),
      bankName: a.bank_name,
      accountName: a.account_name,
      accountNumber: a.account_number,
    })),
  };
}

// ===== 거래처 목록 조회 =====
export async function getVendors(): Promise<{
  success: boolean;
  data: { id: string; name: string }[];
  error?: string;
}> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/clients?per_page=100`;
  const { response, error } = await serverFetch(url, { method: 'GET' });

  if (error) {
    return { success: false, data: [], error: error.message };
  }

  if (!response?.ok) {
    return { success: false, data: [], error: `API 오류: ${response?.status}` };
  }

  const result = await response.json();

  if (!result.success) {
    return { success: false, data: [], error: result.message };
  }

  const clients = result.data?.data || result.data || [];

  return {
    success: true,
    data: clients.map((c: { id: number; name: string }) => ({
      id: String(c.id),
      name: c.name,
    })),
  };
}