package com.nebula.erp.sales.service;

import com.nebula.erp.sales.model.PaymentHistory;
import com.nebula.erp.sales.model.Sales;
import com.nebula.erp.sales.repository.PaymentHistoryRepository;
import com.nebula.erp.sales.repository.SalesRepository;
import com.nebula.erp.sales.requestmodel.PaymentCreditRequest;
import com.nebula.erp.sales.requestmodel.PaymentDebitRequest;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PublicSalesService {

    @Autowired
    private SalesRepository salesRepository;

    @Autowired
    private PaymentHistoryRepository paymentHistoryRepository;

    @Autowired
    private PaymentHistoryService paymentHistoryService;

    /**
     * Public payment confirmation (Used by Razorpay / WhatsApp / External systems)
     */
    @Transactional
    public void confirmPaymentPublic(Long saleId, Double amount) {

        Sales sale = salesRepository.findById(saleId)
                .orElseThrow(() -> new RuntimeException("Sale not found"));

        String tenant = sale.getTenant();

        // Check existing ledger entries
        List<PaymentHistory> existing =
                paymentHistoryRepository.findBySalesIdAndTenant(saleId, tenant);

        boolean hasDebit = existing.stream()
                .anyMatch(e -> "DEBIT".equals(e.getEntry_type()));

        boolean hasPayment = existing.stream()
                .anyMatch(e -> "PAYMENT".equals(e.getEntry_type()));

        // 🔹 Step 1: Create Debit Entry (if not exists)
        if (!hasDebit) {
            PaymentDebitRequest debitReq = new PaymentDebitRequest();
            debitReq.setSales_id(saleId);
            debitReq.setPatient_id(sale.getPatient_id());
            debitReq.setMrn_no(sale.getMrn_no());
            debitReq.setEncounter_id(sale.getEncounter_id());
            debitReq.setCustom_encounter_id(sale.getCustomEncounterId());
            debitReq.setAmount(sale.getTotal_amount());

            paymentHistoryService.addDebit(debitReq);
        }

        // 🔹 Step 2: Add Payment Credit
        if (!hasPayment) {
            PaymentCreditRequest creditReq = new PaymentCreditRequest();
            creditReq.setSales_id(saleId);
            creditReq.setPatient_id(sale.getPatient_id());
            creditReq.setMrn_no(sale.getMrn_no());
            creditReq.setEncounter_id(sale.getEncounter_id());
            creditReq.setCustom_encounter_id(sale.getCustomEncounterId());
            creditReq.setAmount(amount);

            paymentHistoryService.addCreditPublic(creditReq);
        }

        // 🔹 Step 3: Update Payment Status
        double totalPaid =
                paymentHistoryRepository.findTotalPaidForSale(saleId);

        if (totalPaid >= sale.getTotal_amount()) {
            sale.setPayment_status("PAID");
        } else if (totalPaid > 0) {
            sale.setPayment_status("PARTIAL");
        } else {
            sale.setPayment_status("UNPAID");
        }

        salesRepository.save(sale);
    }
}