package com.erp.finance.service.impl;

import com.erp.finance.dto.FinanceReportResponse;
import com.erp.finance.repository.AccountsPayableRepository;
import com.erp.finance.repository.IncomeRecordRepository;
import com.erp.finance.repository.PaymentRecordRepository;
import com.erp.finance.repository.RefundRecordRepository;
import com.erp.finance.service.FinanceReportService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class FinanceReportServiceImpl implements FinanceReportService {

    private final IncomeRecordRepository incomeRecordRepository;
    private final RefundRecordRepository refundRecordRepository;
    private final PaymentRecordRepository paymentRecordRepository;
    private final AccountsPayableRepository apRepository;

    @Override
    public FinanceReportResponse getFinanceSummary(LocalDate startDate, LocalDate endDate) {
        LocalDateTime start = startDate.atStartOfDay();
        LocalDateTime end = endDate.atTime(LocalTime.MAX);

        BigDecimal totalIncome = sumOrZero(incomeRecordRepository.sumConfirmedAmount(start, end));
        BigDecimal totalRefund = sumOrZero(refundRecordRepository.sumCompletedRefundAmount(start, end));
        BigDecimal netIncome = totalIncome.subtract(totalRefund);
        BigDecimal totalPaid = sumOrZero(apRepository.sumPaidAmount(startDate, endDate));
        BigDecimal totalUnpaid = sumOrZero(apRepository.sumTotalUnpaid());
        BigDecimal overdueAmount = sumOrZero(apRepository.sumOverdueAmount(endDate));

        return FinanceReportResponse.builder()
                .startDate(startDate)
                .endDate(endDate)
                .totalIncome(totalIncome)
                .totalRefund(totalRefund)
                .netIncome(netIncome)
                .totalPaid(totalPaid)
                .totalUnpaid(totalUnpaid)
                .overdueAmount(overdueAmount)
                .build();
    }

    @Override
    public FinanceReportResponse getIncomeExpenseReport(LocalDate startDate, LocalDate endDate) {
        return getFinanceSummary(startDate, endDate);
    }

    @Override
    public FinanceReportResponse getPurchasePaymentReport(LocalDate startDate, LocalDate endDate) {
        BigDecimal totalUnpaid = sumOrZero(apRepository.sumTotalUnpaid());
        BigDecimal overdueAmount = sumOrZero(apRepository.sumOverdueAmount(endDate));
        BigDecimal totalPaid = sumOrZero(apRepository.sumPaidAmount(startDate, endDate));

        return FinanceReportResponse.builder()
                .startDate(startDate)
                .endDate(endDate)
                .totalUnpaid(totalUnpaid)
                .overdueAmount(overdueAmount)
                .totalPaid(totalPaid)
                .build();
    }

    private BigDecimal sumOrZero(BigDecimal value) {
        return value != null ? value : BigDecimal.ZERO;
    }
}
