'use server';


import { executeServerAction, type ActionResult } from '@/lib/api/execute-server-action';
import { executePaginatedAction } from '@/lib/api/execute-paginated-action';
import { buildApiUrl } from '@/lib/api/query-params';
import { fetchBankAccountDetailOptions } from '@/lib/api/shared-lookups';
import type { ExpectedExpenseRecord, TransactionType, PaymentStatus, ApprovalStatus } from './types';

// ===== API 응답 타입 =====
interface ExpectedExpenseApiData {
  id: number;
  tenant_id: number;
  expected_payment_date: string;
  settlement_date: string | null;
  transaction_type: string;
  amount: number | string;
  client_id: number | null;
  client_name: string | null;
  bank_account_id: number | null;
  account_code: string | null;
  payment_status: string;
  approval_status: string;
  description: string | null;
  created_at: string;
  updated_at: string;
  client?: { id: number; name: string } | null;
  bank_account?: { id: number; bank_name: string; account_name: string } | null;
}

interface SummaryData {
  total_amount: number;
  total_count: number;
  by_payment_status: Record<string, { count: number; amount: number }>;
  by_transaction_type: Record<string, { count: number; amount: number }>;
  by_month: Record<string, { count: number; amount: number }>;
}

// ===== API → Frontend 변환 =====
function transformApiToFrontend(apiData: ExpectedExpenseApiData): ExpectedExpenseRecord {
  return {
    id: String(apiData.id),
    expectedPaymentDate: apiData.expected_payment_date,
    settlementDate: apiData.settlement_date || '',
    transactionType: (apiData.transaction_type || 'other') as TransactionType,
    amount: typeof apiData.amount === 'string' ? parseFloat(apiData.amount) : apiData.amount,
    vendorId: apiData.client_id ? String(apiData.client_id) : '',
    vendorName: apiData.client_name || apiData.client?.name || '',
    bankAccount: apiData.bank_account ? `${apiData.bank_account.bank_name} ${apiData.bank_account.account_name}` : '',
    accountSubject: apiData.account_code || '',
    paymentStatus: (apiData.payment_status || 'pending') as PaymentStatus,
    approvalStatus: (apiData.approval_status || 'none') as ApprovalStatus,
    note: apiData.description || '',
    createdAt: apiData.created_at,
    updatedAt: apiData.updated_at,
  };
}

// ===== Frontend → API 변환 =====
function transformFrontendToApi(data: Partial<ExpectedExpenseRecord>): Record<string, unknown> {
  const result: Record<string, unknown> = {};
  if (data.expectedPaymentDate !== undefined) result.expected_payment_date = data.expectedPaymentDate;
  if (data.settlementDate !== undefined) result.settlement_date = data.settlementDate || null;
  if (data.transactionType !== undefined) result.transaction_type = data.transactionType;
  if (data.amount !== undefined) result.amount = data.amount;
  if (data.vendorId !== undefined) result.client_id = data.vendorId ? parseInt(data.vendorId, 10) : null;
  if (data.vendorName !== undefined) result.client_name = data.vendorName || null;
  if (data.accountSubject !== undefined) result.account_code = data.accountSubject || null;
  if (data.paymentStatus !== undefined) result.payment_status = data.paymentStatus;
  if (data.approvalStatus !== undefined) result.approval_status = data.approvalStatus;
  if (data.note !== undefined) result.description = data.note || null;
  return result;
}

// ===== 미지급비용 목록 조회 =====
export async function getExpectedExpenses(params?: {
  page?: number; perPage?: number; startDate?: string; endDate?: string;
  transactionType?: string; paymentStatus?: string; approvalStatus?: string;
  clientId?: string; search?: string; sortBy?: string; sortDir?: 'asc' | 'desc';
}) {
  return executePaginatedAction<ExpectedExpenseApiData, ExpectedExpenseRecord>({
    url: buildApiUrl('/api/v1/expected-expenses', {
      page: params?.page,
      per_page: params?.perPage,
      start_date: params?.startDate,
      end_date: params?.endDate,
      transaction_type: params?.transactionType && params.transactionType !== 'all' ? params.transactionType : undefined,
      payment_status: params?.paymentStatus && params.paymentStatus !== 'all' ? params.paymentStatus : undefined,
      approval_status: params?.approvalStatus && params.approvalStatus !== 'all' ? params.approvalStatus : undefined,
      client_id: params?.clientId,
      search: params?.search,
      sort_by: params?.sortBy,
      sort_dir: params?.sortDir,
    }),
    transform: transformApiToFrontend,
    errorMessage: '미지급비용 조회에 실패했습니다.',
  });
}

// ===== 미지급비용 상세 조회 =====
export async function getExpectedExpenseById(id: string): Promise<ActionResult<ExpectedExpenseRecord>> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/expected-expenses/${id}`),
    transform: (data: ExpectedExpenseApiData) => transformApiToFrontend(data),
    errorMessage: '미지급비용 조회에 실패했습니다.',
  });
}

// ===== 미지급비용 등록 =====
export async function createExpectedExpense(data: Partial<ExpectedExpenseRecord>): Promise<ActionResult<ExpectedExpenseRecord>> {
  return executeServerAction({
    url: buildApiUrl('/api/v1/expected-expenses'),
    method: 'POST',
    body: transformFrontendToApi(data),
    transform: (data: ExpectedExpenseApiData) => transformApiToFrontend(data),
    errorMessage: '미지급비용 등록에 실패했습니다.',
  });
}

// ===== 미지급비용 수정 =====
export async function updateExpectedExpense(id: string, data: Partial<ExpectedExpenseRecord>): Promise<ActionResult<ExpectedExpenseRecord>> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/expected-expenses/${id}`),
    method: 'PUT',
    body: transformFrontendToApi(data),
    transform: (data: ExpectedExpenseApiData) => transformApiToFrontend(data),
    errorMessage: '미지급비용 수정에 실패했습니다.',
  });
}

// ===== 미지급비용 삭제 =====
export async function deleteExpectedExpense(id: string): Promise<ActionResult> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/expected-expenses/${id}`),
    method: 'DELETE',
    errorMessage: '미지급비용 삭제에 실패했습니다.',
  });
}

// ===== 미지급비용 일괄 삭제 =====
export async function deleteExpectedExpenses(ids: string[]): Promise<{
  success: boolean; deletedCount?: number; error?: string;
}> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/expected-expenses'),
    method: 'DELETE',
    body: { ids: ids.map(id => parseInt(id, 10)) },
    transform: (data: { deleted_count?: number }) => ({ deletedCount: data?.deleted_count }),
    errorMessage: '미지급비용 일괄 삭제에 실패했습니다.',
  });
  return { success: result.success, deletedCount: result.data?.deletedCount, error: result.error };
}

// ===== 예상 지급일 일괄 변경 =====
export async function updateExpectedPaymentDate(ids: string[], expectedPaymentDate: string): Promise<{
  success: boolean; updatedCount?: number; error?: string;
}> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/expected-expenses/update-payment-date'),
    method: 'PUT',
    body: { ids: ids.map(id => parseInt(id, 10)), expected_payment_date: expectedPaymentDate },
    transform: (data: { updated_count?: number }) => ({ updatedCount: data?.updated_count }),
    errorMessage: '예상 지급일 변경에 실패했습니다.',
  });
  return { success: result.success, updatedCount: result.data?.updatedCount, error: result.error };
}

// ===== 미지급비용 요약 조회 =====
export async function getExpectedExpenseSummary(params?: {
  startDate?: string; endDate?: string; paymentStatus?: string;
}): Promise<ActionResult<SummaryData>> {
  return executeServerAction<SummaryData>({
    url: buildApiUrl('/api/v1/expected-expenses/summary', {
      start_date: params?.startDate,
      end_date: params?.endDate,
      payment_status: params?.paymentStatus && params.paymentStatus !== 'all' ? params.paymentStatus : undefined,
    }),
    errorMessage: '요약 조회에 실패했습니다.',
  });
}

// ===== 거래처 목록 조회 =====
export async function getClients(): Promise<{
  success: boolean; data: { id: string; name: string }[]; error?: string;
}> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/clients', { size: 1000 }),
    transform: (data: { data?: { id: number; name: string }[] } | { id: number; name: string }[]) => {
      type ClientApi = { id: number; name: string };
      const clients: ClientApi[] = Array.isArray(data) ? data : (data as { data?: ClientApi[] })?.data || [];
      return clients.map(c => ({ id: String(c.id), name: c.name }));
    },
    errorMessage: '거래처 조회에 실패했습니다.',
  });
  return { success: result.success, data: result.data || [], error: result.error };
}

// ===== 은행 계좌 목록 조회 =====
export async function getBankAccounts(): Promise<{
  success: boolean; data: { id: string; bankName: string; accountName: string; accountNumber: string }[]; error?: string;
}> {
  const result = await fetchBankAccountDetailOptions();
  return { success: result.success, data: result.data || [], error: result.error };
}
