'use server';


import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { serverFetch } from '@/lib/api/fetch-wrapper';
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 PaginationMeta {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
}

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';
}): Promise<{
  success: boolean;
  data: ExpectedExpenseRecord[];
  pagination: {
    currentPage: number;
    lastPage: number;
    perPage: number;
    total: number;
  };
  error?: string;
}> {
  try {
    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?.transactionType && params.transactionType !== 'all') {
      searchParams.set('transaction_type', params.transactionType);
    }
    if (params?.paymentStatus && params.paymentStatus !== 'all') {
      searchParams.set('payment_status', params.paymentStatus);
    }
    if (params?.approvalStatus && params.approvalStatus !== 'all') {
      searchParams.set('approval_status', params.approvalStatus);
    }
    if (params?.clientId) searchParams.set('client_id', params.clientId);
    if (params?.search) searchParams.set('search', params.search);
    if (params?.sortBy) searchParams.set('sort_by', params.sortBy);
    if (params?.sortDir) searchParams.set('sort_dir', params.sortDir);

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

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

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

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

    const result = await response.json();

    if (!result.success) {
      return {
        success: false,
        data: [],
        pagination: { currentPage: 1, lastPage: 1, perPage: 50, total: 0 },
        error: result.message || '미지급비용 조회에 실패했습니다.',
      };
    }

    const paginationData = result.data;
    const expenses = (paginationData?.data || []).map(transformApiToFrontend);
    const meta: PaginationMeta = {
      current_page: paginationData?.current_page || 1,
      last_page: paginationData?.last_page || 1,
      per_page: paginationData?.per_page || 50,
      total: paginationData?.total || expenses.length,
    };

    return {
      success: true,
      data: expenses,
      pagination: {
        currentPage: meta.current_page,
        lastPage: meta.last_page,
        perPage: meta.per_page,
        total: meta.total,
      },
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] getExpectedExpenses error:', error);
    return {
      success: false,
      data: [],
      pagination: { currentPage: 1, lastPage: 1, perPage: 50, total: 0 },
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 상세 조회 =====
export async function getExpectedExpenseById(id: string): Promise<{
  success: boolean;
  data?: ExpectedExpenseRecord;
  error?: string;
}> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/expected-expenses/${id}`,
      { method: 'GET' }
    );

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

    if (!response?.ok) {
      console.error('[ExpectedExpenseActions] GET expected-expense 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),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] getExpectedExpenseById error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 등록 =====
export async function createExpectedExpense(
  data: Partial<ExpectedExpenseRecord>
): Promise<{ success: boolean; data?: ExpectedExpenseRecord; error?: string }> {
  try {
    const apiData = transformFrontendToApi(data);

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

    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,
      data: transformApiToFrontend(result.data),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] createExpectedExpense error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 수정 =====
export async function updateExpectedExpense(
  id: string,
  data: Partial<ExpectedExpenseRecord>
): Promise<{ success: boolean; data?: ExpectedExpenseRecord; error?: string }> {
  try {
    const apiData = transformFrontendToApi(data);

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

    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,
      data: transformApiToFrontend(result.data),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] updateExpectedExpense error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 삭제 =====
export async function deleteExpectedExpense(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/expected-expenses/${id}`,
      { 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 };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] deleteExpectedExpense error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 일괄 삭제 =====
export async function deleteExpectedExpenses(ids: string[]): Promise<{
  success: boolean;
  deletedCount?: number;
  error?: string;
}> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/expected-expenses`,
      {
        method: 'DELETE',
        body: JSON.stringify({
          ids: ids.map(id => parseInt(id, 10)),
        }),
      }
    );

    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,
      deletedCount: result.data?.deleted_count,
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] deleteExpectedExpenses error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 예상 지급일 일괄 변경 =====
export async function updateExpectedPaymentDate(
  ids: string[],
  expectedPaymentDate: string
): Promise<{
  success: boolean;
  updatedCount?: number;
  error?: string;
}> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/expected-expenses/update-payment-date`,
      {
        method: 'PUT',
        body: JSON.stringify({
          ids: ids.map(id => parseInt(id, 10)),
          expected_payment_date: expectedPaymentDate,
        }),
      }
    );

    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,
      updatedCount: result.data?.updated_count,
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] updateExpectedPaymentDate error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 미지급비용 요약 조회 =====
export async function getExpectedExpenseSummary(params?: {
  startDate?: string;
  endDate?: string;
  paymentStatus?: string;
}): Promise<{
  success: boolean;
  data?: SummaryData;
  error?: string;
}> {
  try {
    const searchParams = new URLSearchParams();

    if (params?.startDate) searchParams.set('start_date', params.startDate);
    if (params?.endDate) searchParams.set('end_date', params.endDate);
    if (params?.paymentStatus && params.paymentStatus !== 'all') {
      searchParams.set('payment_status', params.paymentStatus);
    }

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

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

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

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

    const result = await response.json();

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

    return {
      success: true,
      data: result.data,
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] getExpectedExpenseSummary error:', error);
    return {
      success: false,
      error: '서버 오류가 발생했습니다.',
    };
  }
}

// ===== 거래처 목록 조회 =====
export async function getClients(): Promise<{
  success: boolean;
  data: { id: string; name: string }[];
  error?: string;
}> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/clients?per_page=100`,
      { 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,
      })),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] getClients error:', error);
    return { success: false, data: [], error: '서버 오류가 발생했습니다.' };
  }
}

// ===== 은행 계좌 목록 조회 =====
export async function getBankAccounts(): Promise<{
  success: boolean;
  data: { id: string; bankName: string; accountName: string; accountNumber: string }[];
  error?: string;
}> {
  try {
    const { response, error } = await serverFetch(
      `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bank-accounts?per_page=100`,
      { 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,
      })),
    };
  } catch (error) {
    if (isNextRedirectError(error)) throw error;
    console.error('[ExpectedExpenseActions] getBankAccounts error:', error);
    return { success: false, data: [], error: '서버 오류가 발생했습니다.' };
  }
}