'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 type { CardTransaction, ManualInputFormData, InlineEditData, JournalEntryItem } from './types';
import { getLocalDateString } from '@/lib/utils/date';

// ===== API 응답 타입 =====
interface CardTransactionApiItem {
  id: number;
  card_id: number | null;
  withdrawal_date: string;
  used_at: string | null;
  merchant_name: string | null;
  amount: number | string;
  supply_amount?: number | string;
  tax_amount?: number | string;
  business_number?: string | null;
  account_code: string | null;
  description: string | null;
  deduction_type?: string | null;
  approval_number?: string | null;
  approval_type?: string | null;
  is_hidden?: boolean;
  is_manual?: boolean;
  vendor_name?: string | null;
  card: {
    id: number;
    card_company: string;
    card_number_last4: string;
    card_name: string;
    assigned_user: { id: number; name: string } | null;
  } | null;
  usage_type?: string;
  created_at: string;
  updated_at: string;
}

interface CardTransactionApiSummary {
  previous_month_total: number;
  current_month_total: number;
  total_count: number;
  total_amount: number;
}

// ===== API → Frontend 변환 =====
function transformItem(item: CardTransactionApiItem): CardTransaction {
  const card = item.card;
  const _cardDisplay = card ? `${card.card_company} ${card.card_number_last4}` : '-';
  const usedAtRaw = item.used_at || item.withdrawal_date;
  const usedAtDate = new Date(usedAtRaw);
  const usedAt = item.used_at ? usedAtDate.toISOString().slice(0, 16).replace('T', ' ') : item.withdrawal_date;

  const totalAmount = typeof item.amount === 'string' ? parseFloat(item.amount) : item.amount;
  const supplyAmount = item.supply_amount
    ? (typeof item.supply_amount === 'string' ? parseFloat(item.supply_amount) : item.supply_amount)
    : totalAmount;
  const taxAmount = item.tax_amount
    ? (typeof item.tax_amount === 'string' ? parseFloat(item.tax_amount) : item.tax_amount)
    : 0;

  return {
    id: String(item.id),
    cardCompany: card?.card_company || '-',
    card: card ? `****${card.card_number_last4}` : '-',
    cardName: card?.card_name || '-',
    user: card?.assigned_user?.name || '-',
    usedAt,
    merchantName: item.merchant_name || '-',
    businessNumber: item.business_number || '-',
    vendorName: item.vendor_name || '',
    supplyAmount,
    taxAmount,
    totalAmount: supplyAmount + taxAmount || totalAmount,
    deductionType: item.deduction_type || 'deductible',
    accountSubject: item.account_code || '',
    description: item.description || '',
    approvalNumber: item.approval_number || undefined,
    approvalType: item.approval_type || undefined,
    isHidden: !!item.is_hidden,
    hiddenAt: (item as unknown as { hidden_at?: string }).hidden_at,
    isManual: !!item.is_manual,
    memo: '',
    amount: totalAmount,
    usageType: item.usage_type || '',
    createdAt: item.created_at,
    updatedAt: item.updated_at,
  };
}

// ===== Mock 데이터 (개발용) =====
function generateMockData(): CardTransaction[] {
  const cards = [
    { company: '신한', number: '****3456', name: '법인카드1' },
    { company: 'KB국민', number: '****7890', name: '법인카드2' },
    { company: '현대', number: '****1234', name: '복리후생카드' },
  ];
  const merchants = [
    { name: '스타벅스 강남점', biz: '123-45-67890', vendor: '스타벅스코리아' },
    { name: 'GS25 역삼점', biz: '234-56-78901', vendor: 'GS리테일' },
    { name: '쿠팡', biz: '345-67-89012', vendor: '쿠팡(주)' },
    { name: '교보문고 광화문', biz: '456-78-90123', vendor: '교보문고' },
    { name: '현대주유소', biz: '567-89-01234', vendor: '현대오일뱅크' },
    { name: '삼성전자 서비스', biz: '678-90-12345', vendor: '삼성전자서비스(주)' },
    { name: 'CJ대한통운', biz: '789-01-23456', vendor: 'CJ대한통운(주)' },
    { name: '올리브영 선릉점', biz: '890-12-34567', vendor: 'CJ올리브영' },
  ];
  const descriptions = ['사무용품 구매', '직원 식대', '택배비', '교통비', '복리후생비', '광고비', '소모품비', '통신비'];
  const accounts = ['', 'purchasePayment', 'expenses', 'rent', 'salary', 'insurance', 'utilities'];
  const now = new Date();

  return Array.from({ length: 15 }, (_, i) => {
    const card = cards[i % cards.length];
    const merchant = merchants[i % merchants.length];
    const supply = Math.round((Math.random() * 500000 + 10000) / 100) * 100;
    const tax = Math.round(supply * 0.1);
    const d = new Date(now);
    d.setDate(d.getDate() - i);
    const dateStr = getLocalDateString(d);
    const timeStr = `${String(9 + (i % 10)).padStart(2, '0')}:${String((i * 17) % 60).padStart(2, '0')}`;

    return {
      id: String(1000 + i),
      cardCompany: card.company,
      card: card.number,
      cardName: card.name,
      user: '홍길동',
      usedAt: `${dateStr} ${timeStr}`,
      merchantName: merchant.name,
      businessNumber: merchant.biz,
      vendorName: merchant.vendor,
      supplyAmount: supply,
      taxAmount: tax,
      totalAmount: supply + tax,
      deductionType: i % 3 === 0 ? 'non_deductible' : 'deductible',
      accountSubject: accounts[i % accounts.length],
      description: descriptions[i % descriptions.length],
      isHidden: false,
      isManual: i % 5 === 0,
      memo: '',
      amount: supply + tax,
      usageType: '',
      createdAt: dateStr,
      updatedAt: dateStr,
    };
  });
}

function generateMockHiddenData(): CardTransaction[] {
  return [
    {
      id: '9001', cardCompany: '신한', card: '****3456', cardName: '법인카드1',
      user: '홍길동', usedAt: '2026-02-10 14:30', merchantName: '이마트 역삼점',
      businessNumber: '111-22-33333', vendorName: '이마트(주)',
      supplyAmount: 45000, taxAmount: 4500, totalAmount: 49500,
      deductionType: 'deductible', accountSubject: '', description: '사무용품',
      isHidden: true, hiddenAt: '2026-02-12 09:15', isManual: false, memo: '', amount: 49500, usageType: '',
      createdAt: '2026-02-10', updatedAt: '2026-02-10',
    },
    {
      id: '9002', cardCompany: 'KB국민', card: '****7890', cardName: '법인카드2',
      user: '홍길동', usedAt: '2026-02-08 11:15', merchantName: '다이소 강남점',
      businessNumber: '222-33-44444', vendorName: '아성다이소',
      supplyAmount: 12000, taxAmount: 1200, totalAmount: 13200,
      deductionType: 'non_deductible', accountSubject: '', description: '소모품',
      isHidden: true, hiddenAt: '2026-02-11 16:40', isManual: false, memo: '', amount: 13200, usageType: '',
      createdAt: '2026-02-08', updatedAt: '2026-02-08',
    },
  ];
}

// ===== 카드 거래 목록 조회 =====
export async function getCardTransactionList(params?: {
  page?: number; perPage?: number; startDate?: string; endDate?: string;
  cardId?: number; search?: string; sortBy?: string; sortDir?: 'asc' | 'desc';
  isHidden?: boolean;
}) {
  const result = await executePaginatedAction<CardTransactionApiItem, CardTransaction>({
    url: buildApiUrl('/api/v1/card-transactions', {
      page: params?.page,
      per_page: params?.perPage,
      start_date: params?.startDate,
      end_date: params?.endDate,
      card_id: params?.cardId,
      search: params?.search,
      sort_by: params?.sortBy,
      sort_dir: params?.sortDir,
      is_hidden: params?.isHidden,
    }),
    transform: transformItem,
    errorMessage: '카드 거래 조회에 실패했습니다.',
  });

  // API 빈 응답 시 mock fallback (개발용)
  if (result.success && result.data.length === 0) {
    const mockData = generateMockData();
    return {
      ...result,
      data: mockData,
      pagination: { currentPage: 1, lastPage: 1, perPage: 20, total: mockData.length },
    };
  }
  return result;
}

// ===== 카드 거래 요약 통계 =====
export async function getCardTransactionSummary(params?: {
  startDate?: string; endDate?: string;
}): Promise<ActionResult<{ previousMonthTotal: number; currentMonthTotal: number; totalCount: number; totalAmount: number }>> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/card-transactions/summary', {
      start_date: params?.startDate,
      end_date: params?.endDate,
    }),
    transform: (data: CardTransactionApiSummary) => ({
      previousMonthTotal: data.previous_month_total,
      currentMonthTotal: data.current_month_total,
      totalCount: data.total_count,
      totalAmount: data.total_amount,
    }),
    errorMessage: '요약 조회에 실패했습니다.',
  });

  // Mock fallback (개발용)
  if (!result.success || !result.data) {
    return {
      success: true,
      data: { previousMonthTotal: 8542300, currentMonthTotal: 10802897, totalCount: 15, totalAmount: 10802897 },
    };
  }
  return result;
}

// ===== 카드 거래 단건 조회 =====
export async function getCardTransactionById(id: string): Promise<ActionResult<CardTransaction>> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${id}`),
    transform: (data: CardTransactionApiItem) => transformItem(data),
    errorMessage: '조회에 실패했습니다.',
  });
}

// ===== 카드 거래 등록 (수기 입력) =====
export async function createCardTransaction(data: ManualInputFormData): Promise<ActionResult<CardTransaction>> {
  const usedAt = data.usedTime
    ? `${data.usedDate} ${data.usedTime}`
    : data.usedDate;

  return executeServerAction({
    url: buildApiUrl('/api/v1/card-transactions'),
    method: 'POST',
    body: {
      card_id: data.cardId ? Number(data.cardId) : undefined,
      used_at: usedAt,
      merchant_name: data.merchantName,
      supply_amount: data.supplyAmount,
      tax_amount: data.taxAmount,
      amount: data.supplyAmount + data.taxAmount,
      business_number: data.businessNumber || undefined,
      deduction_type: data.deductionType,
      account_code: data.accountSubject || undefined,
      approval_number: data.approvalNumber || undefined,
      approval_type: data.approvalType,
      description: data.description || undefined,
      vendor_name: data.vendorName || undefined,
      memo: data.memo || undefined,
      is_manual: true,
    },
    transform: (resp: CardTransactionApiItem) => transformItem(resp),
    errorMessage: '등록에 실패했습니다.',
  });
}

// ===== 카드 거래 수정 =====
export async function updateCardTransaction(id: string, data: {
  usedAt?: string; merchantName?: string; amount?: number; memo?: string; usageType?: string;
}): Promise<ActionResult<CardTransaction>> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${id}`),
    method: 'PUT',
    body: {
      used_at: data.usedAt, merchant_name: data.merchantName, amount: data.amount,
      description: data.memo, account_code: data.usageType === 'unset' ? null : data.usageType,
    },
    transform: (resp: CardTransactionApiItem) => transformItem(resp),
    errorMessage: '수정에 실패했습니다.',
  });
}

// ===== 카드 거래 삭제 =====
export async function deleteCardTransaction(id: string): Promise<ActionResult> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${id}`),
    method: 'DELETE',
    errorMessage: '삭제에 실패했습니다.',
  });
}

// ===== 카드 목록 조회 (등록 폼용) =====
export async function getCardList(): Promise<{
  success: boolean; data: Array<{ id: number; name: string; cardNumber: string }>; error?: string;
}> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/cards'),
    transform: (data: { data?: { id: number; card_name: string; card_company: string; card_number_last4: string }[] } | { id: number; card_name: string; card_company: string; card_number_last4: string }[]) => {
      type CardApi = { id: number; card_name: string; card_company: string; card_number_last4: string };
      const cards: CardApi[] = Array.isArray(data) ? data : (data as { data?: CardApi[] })?.data || [];
      return cards.map(c => ({ id: c.id, name: c.card_name, cardNumber: `${c.card_company} ${c.card_number_last4}` }));
    },
    errorMessage: '카드 목록 조회에 실패했습니다.',
  });
  return { success: result.success, data: result.data || [], error: result.error };
}

// ===== 계정과목 일괄 수정 =====
export async function bulkUpdateAccountCode(ids: number[], accountCode: string): Promise<{
  success: boolean; updatedCount?: number; error?: string;
}> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/card-transactions/bulk-update-account'),
    method: 'PUT',
    body: { ids, account_code: accountCode },
    transform: (data: { updated_count?: number }) => ({ updatedCount: data?.updated_count || 0 }),
    errorMessage: '계정과목 수정에 실패했습니다.',
  });
  return { success: result.success, updatedCount: result.data?.updatedCount, error: result.error };
}

// ===== 인라인 편집 일괄 저장 =====
export async function bulkSaveInlineEdits(
  edits: Record<string, InlineEditData>
): Promise<ActionResult> {
  const items = Object.entries(edits).map(([id, data]) => ({
    id: Number(id),
    deduction_type: data.deductionType,
    account_code: data.accountSubject,
    description: data.description,
  }));

  return executeServerAction({
    url: buildApiUrl('/api/v1/card-transactions/bulk-update'),
    method: 'PUT',
    body: { items },
    errorMessage: '일괄 저장에 실패했습니다.',
  });
}

// ===== 거래 숨김 처리 =====
export async function hideTransaction(id: string): Promise<ActionResult> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${id}/hide`),
    method: 'PUT',
    errorMessage: '숨김 처리에 실패했습니다.',
  });
}

// ===== 거래 숨김 해제 (복원) =====
export async function unhideTransaction(id: string): Promise<ActionResult> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${id}/unhide`),
    method: 'PUT',
    errorMessage: '복원에 실패했습니다.',
  });
}

// ===== 숨김 처리된 거래 목록 =====
export async function getHiddenTransactions(params?: {
  startDate?: string; endDate?: string;
}) {
  const result = await executePaginatedAction<CardTransactionApiItem, CardTransaction>({
    url: buildApiUrl('/api/v1/card-transactions', {
      start_date: params?.startDate,
      end_date: params?.endDate,
      is_hidden: true,
    }),
    transform: transformItem,
    errorMessage: '숨김 거래 조회에 실패했습니다.',
  });

  // Mock fallback (개발용)
  if (result.success && result.data.length === 0) {
    const mockHidden = generateMockHiddenData();
    return { ...result, data: mockHidden, pagination: { currentPage: 1, lastPage: 1, perPage: 20, total: mockHidden.length } };
  }
  return result;
}

// ===== 분개 항목 저장 =====
export async function saveJournalEntries(
  transactionId: string,
  items: JournalEntryItem[]
): Promise<ActionResult> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${transactionId}/journal-entries`),
    method: 'POST',
    body: {
      items: items.map(item => ({
        supply_amount: item.supplyAmount,
        tax_amount: item.taxAmount,
        account_code: item.accountSubject,
        deduction_type: item.deductionType,
        vendor_name: item.vendorName,
        description: item.description,
        memo: item.memo,
      })),
    },
    errorMessage: '분개 저장에 실패했습니다.',
  });
}

// ===== 분개 항목 조회 =====
export async function getJournalEntries(
  transactionId: string
): Promise<ActionResult<JournalEntryItem[]>> {
  return executeServerAction({
    url: buildApiUrl(`/api/v1/card-transactions/${transactionId}/journal-entries`),
    transform: (data: { items?: Array<{
      id?: number; supply_amount: number; tax_amount: number;
      account_code: string; deduction_type: string; vendor_name: string;
      description: string; memo: string;
    }> }) => {
      return (data.items || []).map(item => ({
        id: item.id ? String(item.id) : undefined,
        supplyAmount: item.supply_amount,
        taxAmount: item.tax_amount,
        totalAmount: item.supply_amount + item.tax_amount,
        accountSubject: item.account_code || '',
        deductionType: item.deduction_type || 'deductible',
        vendorName: item.vendor_name || '',
        description: item.description || '',
        memo: item.memo || '',
      }));
    },
    errorMessage: '분개 조회에 실패했습니다.',
  });
}
