import { api } from './api';
import { PageResponse, PageRequest } from '@/types/backend';
import {
  PaymentBatchDTO,
  CreatePaymentBatchDTO,
  UpdatePaymentBatchStatusDTO,
  PaymentOrderDTO,
  CreatePaymentOrderDTO,
  UpdatePaymentOrderStatusDTO,
  TreasuryPaymentDTO,
  CreateTreasuryPaymentDTO,
  CashAccountDTO,
  CreateCashAccountDTO,
  TreasuryEntryDTO,
  CreateTreasuryEntryDTO,
  PaymentAuthorizationDTO,
  CreatePaymentAuthorizationDTO,
  ApprovePaymentDTO,
  RejectPaymentDTO,
  CashFlowDTO,
  CreateCashFlowDTO,
  BankReconciliationDTO,
  CreateBankReconciliationDTO,
  ReconciliationItemDTO,
} from '@/types/treasury';

const PAYMENT_BATCHES_URL = '/treasury/payment-batches';
const PAYMENT_ORDERS_URL = '/treasury/payment-orders';
const TREASURY_PAYMENTS_URL = '/treasury/payments';

export const treasuryService = {
  // Payment Batches
  getPaymentBatches: async (pageRequest: PageRequest & {
    periodId?: number;
    ministryId?: string;
    status?: string;
  }): Promise<PageResponse<PaymentBatchDTO>> => {
    const {
      page = 0,
      size = 20,
      sortBy,
      sortDirection,
      periodId,
      ministryId,
      status,
    } = pageRequest;
    const params = new URLSearchParams();
    params.append('page', page.toString());
    params.append('size', size.toString());
    if (sortBy) {
      params.append('sortBy', sortBy);
    }
    if (sortDirection) {
      params.append('sortDirection', sortDirection);
    }
    if (periodId) {
      params.append('periodId', periodId.toString());
    }
    if (ministryId) {
      params.append('ministryId', ministryId);
    }
    if (status) {
      params.append('status', status);
    }
    return api.getPage<PaymentBatchDTO>(`${PAYMENT_BATCHES_URL}?${params.toString()}`);
  },

  getPaymentBatchById: async (id: string): Promise<PaymentBatchDTO> => {
    return api.get<PaymentBatchDTO>(`${PAYMENT_BATCHES_URL}/${id}`);
  },

  createPaymentBatch: async (dto: CreatePaymentBatchDTO): Promise<PaymentBatchDTO> => {
    return api.post<PaymentBatchDTO>(PAYMENT_BATCHES_URL, dto);
  },

  updatePaymentBatchStatus: async (id: string, dto: UpdatePaymentBatchStatusDTO): Promise<PaymentBatchDTO> => {
    return api.post<PaymentBatchDTO>(`${PAYMENT_BATCHES_URL}/${id}/status`, dto);
  },

  // Payment Orders
  getPaymentOrders: async (pageRequest: PageRequest & {
    batchId?: string;
    status?: string;
  }): Promise<PageResponse<PaymentOrderDTO>> => {
    const {
      page = 0,
      size = 20,
      sortBy,
      sortDirection,
      batchId,
      status,
    } = pageRequest;
    const params = new URLSearchParams();
    params.append('page', page.toString());
    params.append('size', size.toString());
    if (sortBy) {
      params.append('sortBy', sortBy);
    }
    if (sortDirection) {
      params.append('sortDirection', sortDirection);
    }
    if (batchId) {
      params.append('batchId', batchId);
    }
    if (status) {
      params.append('status', status);
    }
    return api.getPage<PaymentOrderDTO>(`${PAYMENT_ORDERS_URL}?${params.toString()}`);
  },

  getPaymentOrderById: async (id: string): Promise<PaymentOrderDTO> => {
    return api.get<PaymentOrderDTO>(`${PAYMENT_ORDERS_URL}/${id}`);
  },

  createPaymentOrder: async (dto: CreatePaymentOrderDTO): Promise<PaymentOrderDTO> => {
    return api.post<PaymentOrderDTO>(PAYMENT_ORDERS_URL, dto);
  },

  updatePaymentOrderStatus: async (id: string, dto: UpdatePaymentOrderStatusDTO): Promise<PaymentOrderDTO> => {
    return api.post<PaymentOrderDTO>(`${PAYMENT_ORDERS_URL}/${id}/status`, dto);
  },

  // Treasury Payments
  getTreasuryPayments: async (pageRequest: PageRequest & {
    paymentOrderId?: string;
    status?: string;
  }): Promise<PageResponse<TreasuryPaymentDTO>> => {
    const {
      page = 0,
      size = 20,
      sortBy,
      sortDirection,
      paymentOrderId,
      status,
    } = pageRequest;
    const params = new URLSearchParams();
    params.append('page', page.toString());
    params.append('size', size.toString());
    if (sortBy) {
      params.append('sortBy', sortBy);
    }
    if (sortDirection) {
      params.append('sortDirection', sortDirection);
    }
    if (paymentOrderId) {
      params.append('paymentOrderId', paymentOrderId);
    }
    if (status) {
      params.append('status', status);
    }
    return api.getPage<TreasuryPaymentDTO>(`${TREASURY_PAYMENTS_URL}?${params.toString()}`);
  },

  createTreasuryPayment: async (dto: CreateTreasuryPaymentDTO): Promise<TreasuryPaymentDTO> => {
    return api.post<TreasuryPaymentDTO>(TREASURY_PAYMENTS_URL, dto);
  },

  // Cash Accounts
  getCashAccounts: async (params?: { type?: string; activeOnly?: boolean }): Promise<CashAccountDTO[]> => {
    const queryParams = new URLSearchParams();
    if (params?.type) queryParams.append('type', params.type);
    if (params?.activeOnly !== undefined) queryParams.append('activeOnly', params.activeOnly.toString());
    const url = `/treasury/cash-accounts${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
    return api.get<CashAccountDTO[]>(url);
  },

  getCashAccountById: async (id: string): Promise<CashAccountDTO> => {
    return api.get<CashAccountDTO>(`/treasury/cash-accounts/${id}`);
  },

  createCashAccount: async (dto: CreateCashAccountDTO): Promise<CashAccountDTO> => {
    return api.post<CashAccountDTO>('/treasury/cash-accounts', dto);
  },

  getAvailableBalance: async (id: string): Promise<number> => {
    return api.get<number>(`/treasury/cash-accounts/${id}/available-balance`);
  },

  getCurrentBalance: async (id: string): Promise<number> => {
    return api.get<number>(`/treasury/cash-accounts/${id}/current-balance`);
  },

  // Treasury Entries
  getTreasuryEntries: async (pageRequest: PageRequest & {
    cashAccountId?: string;
    type?: string;
    status?: string;
  }): Promise<PageResponse<TreasuryEntryDTO>> => {
    const { page = 0, size = 20, sortBy, sortDirection, cashAccountId, type, status } = pageRequest;
    const params = new URLSearchParams();
    params.append('page', page.toString());
    params.append('size', size.toString());
    if (sortBy) params.append('sortBy', sortBy);
    if (sortDirection) params.append('sortDirection', sortDirection);
    if (cashAccountId) params.append('cashAccountId', cashAccountId);
    if (type) params.append('type', type);
    if (status) params.append('status', status);
    return api.getPage<TreasuryEntryDTO>(`/treasury/entries?${params.toString()}`);
  },

  getTreasuryEntryById: async (id: string): Promise<TreasuryEntryDTO> => {
    return api.get<TreasuryEntryDTO>(`/treasury/entries/${id}`);
  },

  createTreasuryEntry: async (dto: CreateTreasuryEntryDTO): Promise<TreasuryEntryDTO> => {
    return api.post<TreasuryEntryDTO>('/treasury/entries', dto);
  },

  // Payment Authorizations
  getPaymentAuthorizations: async (params?: {
    paymentOrderId?: string;
    paymentBatchId?: string;
    approverId?: string;
  }): Promise<PaymentAuthorizationDTO[]> => {
    const queryParams = new URLSearchParams();
    if (params?.paymentOrderId) queryParams.append('paymentOrderId', params.paymentOrderId);
    if (params?.paymentBatchId) queryParams.append('paymentBatchId', params.paymentBatchId);
    if (params?.approverId) queryParams.append('approverId', params.approverId);
    const url = `/treasury/authorizations${queryParams.toString() ? '?' + queryParams.toString() : ''}`;
    return api.get<PaymentAuthorizationDTO[]>(url);
  },

  getPendingApprovals: async (approverId: string): Promise<PaymentAuthorizationDTO[]> => {
    return api.get<PaymentAuthorizationDTO[]>(`/treasury/authorizations/pending?approverId=${approverId}`);
  },

  requestAuthorization: async (dto: CreatePaymentAuthorizationDTO): Promise<PaymentAuthorizationDTO> => {
    return api.post<PaymentAuthorizationDTO>('/treasury/authorizations', dto);
  },

  approvePayment: async (id: string, dto: ApprovePaymentDTO): Promise<PaymentAuthorizationDTO> => {
    return api.post<PaymentAuthorizationDTO>(`/treasury/authorizations/${id}/approve`, dto);
  },

  rejectPayment: async (id: string, dto: RejectPaymentDTO): Promise<PaymentAuthorizationDTO> => {
    return api.post<PaymentAuthorizationDTO>(`/treasury/authorizations/${id}/reject`, dto);
  },

  // Cash Flow
  getCashFlows: async (pageRequest: PageRequest & {
    cashAccountId: string;
    startDate?: string;
    endDate?: string;
  }): Promise<PageResponse<CashFlowDTO>> => {
    const { page = 0, size = 20, sortBy, sortDirection, cashAccountId, startDate, endDate } = pageRequest;
    const params = new URLSearchParams();
    params.append('cashAccountId', cashAccountId);
    params.append('page', page.toString());
    params.append('size', size.toString());
    if (sortBy) params.append('sortBy', sortBy);
    if (sortDirection) params.append('sortDirection', sortDirection);
    if (startDate) params.append('startDate', startDate);
    if (endDate) params.append('endDate', endDate);
    return api.getPage<CashFlowDTO>(`/treasury/cash-flow?${params.toString()}`);
  },

  registerCashFlow: async (dto: CreateCashFlowDTO): Promise<CashFlowDTO> => {
    return api.post<CashFlowDTO>('/treasury/cash-flow', dto);
  },

  getFlowSummary: async (cashAccountId: string, startDate: string, endDate: string): Promise<{
    totalInflow: number;
    totalOutflow: number;
    netFlow: number;
  }> => {
    return api.get(`/treasury/cash-flow/${cashAccountId}/summary?startDate=${startDate}&endDate=${endDate}`);
  },

  // Bank Reconciliation
  getBankReconciliations: async (cashAccountId?: string): Promise<BankReconciliationDTO[]> => {
    const url = cashAccountId 
      ? `/treasury/reconciliations/cash-account/${cashAccountId}`
      : '/treasury/reconciliations';
    return api.get<BankReconciliationDTO[]>(url);
  },

  getBankReconciliationById: async (id: string): Promise<BankReconciliationDTO> => {
    return api.get<BankReconciliationDTO>(`/treasury/reconciliations/${id}`);
  },

  importStatement: async (dto: CreateBankReconciliationDTO): Promise<BankReconciliationDTO> => {
    return api.post<BankReconciliationDTO>('/treasury/reconciliations', dto);
  },

  reconcile: async (id: string): Promise<BankReconciliationDTO> => {
    return api.post<BankReconciliationDTO>(`/treasury/reconciliations/${id}/reconcile`, {});
  },

  finalizeReconciliation: async (id: string, reconciledBy: string): Promise<BankReconciliationDTO> => {
    return api.post<BankReconciliationDTO>(`/treasury/reconciliations/${id}/finalize?reconciledBy=${reconciledBy}`, {});
  },

  getUnmatchedItems: async (id: string): Promise<ReconciliationItemDTO[]> => {
    return api.get<ReconciliationItemDTO[]>(`/treasury/reconciliations/${id}/unmatched-items`);
  },
};

