'use server';


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

// ===== API 응답 타입 =====
interface WithdrawalApiData {
  id: number;
  tenant_id: number;
  withdrawal_date: string;
  used_at: string | null;
  amount: number | string;           // API 실제 필드명
  client_id: number | null;          // API 실제 필드명
  client_name: string | null;        // API 실제 필드명
  merchant_name: string | null;      // API 실제 필드명 (가맹점명)
  bank_account_id: number | null;
  card_id: number | null;
  payment_method: string | null;     // API 실제 필드명 (결제수단)
  account_code: string | null;       // API 실제 필드명 (계정과목)
  description: string | null;        // API 실제 필드명
  reference_type: string | null;
  reference_id: number | null;
  created_at: string;
  updated_at: string;
  // 관계 데이터
  client?: { id: number; name: string } | null;
  bank_account?: { id: number; bank_name: string; account_name: string } | null;
  card?: { id: number; card_name: string } | null;
}

interface PaginationMeta {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

// ===== API → Frontend 변환 =====
function transformApiToFrontend(apiData: WithdrawalApiData): WithdrawalRecord {
  return {
    id: String(apiData.id),
    withdrawalDate: apiData.withdrawal_date,
    withdrawalAmount: typeof apiData.amount === 'string'
      ? parseFloat(apiData.amount)
      : (apiData.amount ?? 0),
    bankAccountId: apiData.bank_account_id ? String(apiData.bank_account_id) : '',
    accountName: apiData.bank_account
      ? `${apiData.bank_account.bank_name} ${apiData.bank_account.account_name}`
      : '',
    recipientName: apiData.merchant_name || apiData.client_name || apiData.client?.name || '',
    note: apiData.description || '',
    withdrawalType: (apiData.account_code || 'unset') as WithdrawalType,
    vendorId: apiData.client_id ? String(apiData.client_id) : '',
    vendorName: apiData.client?.name || apiData.client_name || '',
    createdAt: apiData.created_at,
    updatedAt: apiData.updated_at,
  };
}

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

  if (data.withdrawalDate !== undefined) result.withdrawal_date = data.withdrawalDate;
  if (data.withdrawalAmount !== undefined) result.amount = data.withdrawalAmount;
  if (data.recipientName !== undefined) result.client_name = data.recipientName;
  if (data.note !== undefined) result.description = data.note || null;
  // 'unset'은 미설정 상태이므로 API에 null로 전송
  if (data.withdrawalType !== undefined) {
    result.account_code = data.withdrawalType === 'unset' ? null : data.withdrawalType;
  }
  if (data.vendorId !== undefined) result.client_id = data.vendorId ? parseInt(data.vendorId, 10) : null;
  // 계좌 ID
  if (data.bankAccountId !== undefined) {
    result.bank_account_id = data.bankAccountId ? parseInt(data.bankAccountId, 10) : null;
  }
  // payment_method는 API 필수 필드 - 기본값 'transfer'(계좌이체)
  // 유효값: cash, transfer, card, check
  result.payment_method = 'transfer';

  return result;
}

// ===== 출금 내역 조회 =====
export async function getWithdrawals(params?: {
  page?: number;
  perPage?: number;
  startDate?: string;
  endDate?: string;
  withdrawalType?: string;
  vendor?: string;
  search?: string;
}): Promise<{
  success: boolean;
  data: WithdrawalRecord[];
  pagination: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
  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?.withdrawalType && params.withdrawalType !== 'all') {
    searchParams.set('withdrawal_type', params.withdrawalType);
  }
  if (params?.vendor && params.vendor !== 'all') {
    searchParams.set('vendor', params.vendor);
  }
  if (params?.search) searchParams.set('search', params.search);

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

  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('[WithdrawalActions] GET withdrawals 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 || '출금 내역 조회에 실패했습니다.',
    };
  }

  // API 응답 구조 처리: { data: { data: [...], current_page: ... } } 또는 { data: [...], meta: {...} }
  const isPaginatedResponse = result.data && typeof result.data === 'object' && 'data' in result.data && Array.isArray(result.data.data);
  const rawData = isPaginatedResponse ? result.data.data : (Array.isArray(result.data) ? result.data : []);
  const withdrawals = rawData.map(transformApiToFrontend);

  const meta: PaginationMeta = isPaginatedResponse
    ? {
        current_page: result.data.current_page || 1,
        last_page: result.data.last_page || 1,
        per_page: result.data.per_page || 20,
        total: result.data.total || withdrawals.length,
      }
    : result.meta || {
        current_page: 1,
        last_page: 1,
        per_page: 20,
        total: withdrawals.length,
      };

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

// ===== 출금 내역 삭제 =====
export async function deleteWithdrawal(id: string): Promise<{ success: boolean; error?: string }> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/withdrawals/${id}`;
  const { response, error } = await serverFetch(url, { method: 'DELETE' });

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

  const result = await response?.json();

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

  return { success: true };
}

// ===== 계정과목명 일괄 저장 =====
export async function updateWithdrawalTypes(
  ids: string[],
  withdrawalType: string
): Promise<{ success: boolean; error?: string }> {
  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/withdrawals/bulk-update-type`;
  const { response, error } = await serverFetch(url, {
    method: 'PUT',
    body: JSON.stringify({
      ids: ids.map(id => parseInt(id, 10)),
      withdrawal_type: withdrawalType,
    }),
  });

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

  const result = await response?.json();

  if (!response?.ok || !result.success) {
    return { success: false, error: result?.message || '계정과목명 저장에 실패했습니다.' };
  }

  return { success: true };
}

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

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

  if (!response?.ok) {
    console.error('[WithdrawalActions] GET withdrawal 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 createWithdrawal(
  data: Partial<WithdrawalRecord>
): Promise<{ success: boolean; data?: WithdrawalRecord; error?: string }> {
  const apiData = transformFrontendToApi(data);
  console.log('[WithdrawalActions] POST withdrawal request:', apiData);

  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/withdrawals`;
  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('[WithdrawalActions] POST withdrawal response:', result);

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

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

// ===== 출금 수정 =====
export async function updateWithdrawal(
  id: string,
  data: Partial<WithdrawalRecord>
): Promise<{ success: boolean; data?: WithdrawalRecord; error?: string }> {
  const apiData = transformFrontendToApi(data);
  console.log('[WithdrawalActions] PUT withdrawal request:', apiData);

  const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/withdrawals/${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('[WithdrawalActions] PUT withdrawal response:', result);

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

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

// ===== 거래처 목록 조회 =====
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,
    })),
  };
}

// ===== 계좌 목록 조회 =====
export async function getBankAccounts(): Promise<{
  success: boolean;
  data: { id: string; name: 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; account_name: string; bank_name: string }) => ({
      id: String(a.id),
      name: `${a.bank_name} ${a.account_name}`,
    })),
  };
}
