package com.eksad.masterdata.service;

import com.eksad.ddms.common.dto.CreationalSpecificationDTO;
import com.eksad.ddms.common.h2.uri.claimc2.ClaimC2URI;
import com.eksad.ddms.common.h2.uri.claimkpb.ClaimKPBURI;
import com.eksad.ddms.common.h2.uri.integrasi.IntegrasiURI;
import com.eksad.ddms.common.uri.PartURI;
import com.eksad.ddms.common.util.StringUtil;
import com.eksad.ddms.common.util.response.ResponseDTO;
import com.eksad.masterdata.common.RequestUtil;
import com.eksad.masterdata.common.dto.*;
import com.eksad.masterdata.common.listEnum.*;
import com.eksad.masterdata.domain.*;
import com.eksad.masterdata.domain.assembler.*;
import com.eksad.masterdata.domain.workorder.WorkOrder;
import com.eksad.masterdata.repository.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import jakarta.transaction.Transactional;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

@Service
@PropertySources({
        @PropertySource("classpath:application.properties")
        ,
        @PropertySource("classpath:error-message.properties")
})
public class WorkOrderHystrixService {

    @Autowired
    PaymentRepository paymentRepository;

    @Autowired
    WorkOrderRepositoryImpl workOrderRepositoryImpl;

    @Autowired
    PromoRepository promoRepository;

    @Autowired
    WorkOrderRepository workOrderRepository;

    @Autowired
    CustomerFeedbackRepository customerFeedbackRepository;

    @Autowired
    ConfigWorkshopServiceRepository cwsRepository;

    @Autowired
    WorkshopServiceRepository workshopServiceRepository;

    @Autowired
    CustomerAttendeeRepository custAttendeeRepository;

    @Autowired
    UnitCustomerRepository unitCustomerRepository;

    @Autowired
    KartuKPBRepository kartuKPBRepository;

    @Autowired
    WorkshopServiceRepository wsRepository;

    @Autowired
    ConfigWorkshopServiceRepository configWorkshopServiceRepository;

    @Autowired
    MarketTreatmentRepository marketTreatmentRepository;

    @Autowired
    WorkOrderMonitoringRepository workOrderMonitoringRepository;

    @Autowired
    CSMonitoringRepository csMonitoringRepository;

    @Autowired
    CustContractServiceRepository custContractServiceRepository;

    @Autowired
    ConfigPackageServicePartPromoRepository configPackageServicePartPromoRepository;

    @Value("${dam.claim.h2}")
    private String claim_url;

    @Value("${ddms.h2.service.slave}")
    private String DDMS_H2_SERVICE_SLAVE;

    @Autowired
    Environment env;

    RestTemplate restTemplate = new RestTemplate();

    @Transactional
    @HystrixCommand(fallbackMethod = "completeWoFallback")
    public ResponseEntity<ResponseDTO> completeWorkOrder(RequestCompletePaymentWorkOrderDTO bodyDto) {
        try {
            WorkOrder woData = workOrderRepositoryImpl.findOneWoByWoIDOptimis(bodyDto.getWorkOrderDTO().getWoID());
            if (woData == null) {
                return ResponseEntity.status(HttpStatus.OK).body(
                        new ResponseDTO().failedRespose(String.valueOf(HttpStatus.NOT_FOUND.value()), "Mohon refresh halaman"));
            }
            WorkOrderDTO dto = bodyDto.getWorkOrderDTO();
            PaymentH2DTO paymentDTO = bodyDto.getPaymentDTO();
            Boolean isPaymentComplete = bodyDto.getIsPaymentComplete();
            String msg = env.getProperty("data.not.found.message");
            msg = MessageFormat.format(msg, bodyDto.getWorkOrderDTO().getWoID());
            Validate.notNull(woData, msg);
            if (woData != null) {
                if (!isPaymentComplete) {

                    /*
                     *   Insert Payment
                     */
                    Payment insertPayment = paymentRepository.findOneByPaymentID(paymentDTO.getPaymentID());
                    if (insertPayment == null) {
                        insertPayment = new PaymentAssembler().toDomain(paymentDTO);
                        if (paymentDTO.getJumlahDiskonEvoucher() != null) {
                            insertPayment.setJumlahDiskonEvoucher(paymentDTO.getJumlahDiskonEvoucher());
                            if (paymentDTO.getJumlahDiskon() == null) {
                                insertPayment.setJumlahDiskon(0.0);
                            } else if (paymentDTO.getJumlahDiskon() == 0) {
                                insertPayment.setJumlahDiskon(paymentDTO.getJumlahDiskon());
                            } else {
                                insertPayment.setJumlahDiskon(paymentDTO.getJumlahDiskon() - paymentDTO.getJumlahDiskonEvoucher());
                            }
                        } else {
                            insertPayment.setJumlahDiskon(paymentDTO.getJumlahDiskon());
                        }
                    } else {
                        insertPayment.setPaymentID(paymentDTO.getPaymentID());
                        insertPayment.setWoID(paymentDTO.getWoID());
                        insertPayment.setPaymentMethod(paymentDTO.getPaymentMethod());
                        insertPayment.setPaymentStatus(paymentDTO.getPaymentStatus());
                        insertPayment.setVoucherCode(paymentDTO.getVoucherCode());
                        insertPayment.setJumlahPembayaran(paymentDTO.getJumlahPembayaran());
                        insertPayment.setNoTransfer(paymentDTO.getNoTransfer());
                        insertPayment.setNokartuKredit(paymentDTO.getNokartuKredit());
                        insertPayment.setTerbilang(paymentDTO.getTerbilang());
                        insertPayment.setPaymentDate(paymentDTO.getPaymentDate());
                        insertPayment.setDateReport(paymentDTO.getDateReport());
                        insertPayment.setAngka(paymentDTO.getAngka());
                        insertPayment.setPresentase(paymentDTO.getPresentase());
                        insertPayment.setTotalBayar(paymentDTO.getTotalBayar());
                        insertPayment.setJumlahDiskon(paymentDTO.getJumlahDiskon() == null ? 0.0 : paymentDTO.getJumlahDiskon());
                        insertPayment.setNoKwitansi(paymentDTO.getNoKwitansi());
                        insertPayment.setTotalBayarExcludeHO(paymentDTO.getTotalBayarExcludeHO());
                        insertPayment.setJumlahPembayaranExcludeHO(paymentDTO.getJumlahPembayaranExcludeHO());
                        insertPayment.setTandaJadi(paymentDTO.getTandaJadi());
                        insertPayment.getPaymentCreational().setModifiedAt(new Date());
                        insertPayment.getPaymentCreational().setModifiedBy(paymentDTO.getPaymentCreationalDTO().getModifiedBy());
                        insertPayment.setListPromo(dto.getListPromo().stream().map(promo -> {
                            Promo promoFound = promoRepository.findOneByPromoIDAndPromoStatus(promo.getPromoID(), com.eksad.ddms.common.util.status.DataStatus.ACTIVE);
                            return promoFound;
                        }).collect(Collectors.toCollection(LinkedList::new)));
                    }
                    paymentRepository.save(insertPayment);
                    //                }

                    WorkOrder dataWO = workOrderRepository.findOneByWoID(dto.getWoID());
                    //validasi UNPAID tapi WO COMPLETE
                    Payment checkPayment = paymentRepository.findOneByWoID(dataWO.getWoID());
                    for (int i = 0; i < 3; i++) {
                        if (checkPayment == null) {
                            paymentRepository.save(insertPayment);
                            checkPayment = paymentRepository.findOneByWoID(dataWO.getWoID());
                        } else {
                            break;
                        }
                    }
                    /*
                     *  Update Work Order
                     */

//                    String msg = env.getProperty("data.not.found.message");
//                    msg = MessageFormat.format(msg, dto.getWoID());
                    Validate.notNull(dataWO, msg);
                    updateWorkOrderData(dataWO, dto);
                    workOrderRepository.save(dataWO);



                    /* Jika belum pernah Complete payment */
//            if(!isPaymentComplete) {
                    /*
                     *   Insert Customer Feedback
                     */
                    CustomerFeedback custFBExist;
                    String custFBID;
                    do {
                        //generate custfeedback id
                        custFBID = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
                        custFBExist = customerFeedbackRepository.findOneByCustFeedbackID(custFBID);
                    } while (custFBExist != null);
                    CustomerFeedback postCustFeed = new CustomerFeedback();
                    postCustFeed.setCustFeedbackID(custFBID);
                    postCustFeed.setAhassID(dto.getAhassID());
                    postCustFeed.setCustFeedbackStatus(com.eksad.ddms.common.util.status.DataStatus.INACTIVE);
                    postCustFeed.setJenisService(defineJenisService(dto)); //TODO
                    postCustFeed.setNoPolisi(dto.getNoPolisi());
                    postCustFeed.setNoTelp(dto.getConfirmNoTelp());
                    postCustFeed.setUnitCustomerID(dto.getUnitCustomerID());
                    postCustFeed.setUnitCustomerName(dto.getUnitCustomerName());
                    postCustFeed.setUnitTypeID(dto.getUnitTypeID());
                    postCustFeed.setUnitTypeName(dto.getUnitTypeName());
                    postCustFeed.setWoID(dto.getWoID());
                    postCustFeed.setCustFeedbackCreational(new CreationalSpecification(new Date(), dto.getWoCreationalDTO().getModifiedBy(), new Date(), dto.getWoCreationalDTO().getModifiedBy()));
                    customerFeedbackRepository.save(postCustFeed);

                    /*
                     *   Insert Claim KPB
                     */
                    for (WorkOrderServiceDTO jasa : dto.getListJasa()) {
                        //                       if((jasa.getKpb() || jasa.getKpb().equals(Boolean.TRUE)) || jasa.getSource().contains("KPB")) {
                        //                           insertClaimKPB(dto, jasa);
                        //                       }
                        if (jasa.getConfigWorkshopServiceID().substring(0, 2).equalsIgnoreCase("WS")) {
                            WorkshopService ws = workshopServiceRepository.findOneByWorkshopServiceID(jasa.getConfigWorkshopServiceID());
                            if (ws != null) {
                                if (ws.getServiceCategory().equalsIgnoreCase("ASS 1") || ws.getServiceCategory().equalsIgnoreCase("ASS 2")
                                        || ws.getServiceCategory().equalsIgnoreCase("ASS 3") || ws.getServiceCategory().equalsIgnoreCase("ASS 4")) {
                                    System.out.println("[INSERT KPB] = " + dto.getWoID() + " " + ws.getServiceCategory());
                                    insertClaimKPB(dto, jasa);
                                }
                            }
                        }
                    }

                    /*
                     *   Insert Claim C2
                     */
//                    for (WorkOrderSparepartDTO part : dto.getListPart()) {
//                        if (part.getC2() || part.getC2().equals(Boolean.TRUE)) {
//                            insertClaimC2(dto, part);
//                        }
//                    }
                    List<WorkOrderSparepartDTO> part = dto.getListPart().stream().filter(p -> p.getC2()).collect(Collectors.toList());
                    if (!part.isEmpty()) {
                        insertClaimC2(dto, part);
                    }


                    /*
                     *   Update Market Treatment
                     */
                    if (dto.getWoID().contains("MKT")) {
                        String[] delimiter = dto.getWoID().split("-");
                        if (delimiter[3].equalsIgnoreCase("MKT")) {
                            List<MarketTreatment> listTemp = marketTreatmentRepository.findAllByNomorMesinIgnoreCaseAndMarketTreatmentStatus(dto.getWoNoMesin(), com.eksad.ddms.common.util.status.DataStatus.ACTIVE);
                            if (listTemp.size() > 0) {
                                MarketTreatment mkt = listTemp.get(0);
                                mkt.setMarketTreatmentStatus(com.eksad.ddms.common.util.status.DataStatus.INACTIVE);
                                marketTreatmentRepository.save(mkt);
                            }
                        }
                    }

                    /*
                     *  Insert WO Monitoring
                     */
                    WorkOrderMonitoring woMonitorExist;
                    String woMonitorID;
                    do {
                        //generate WO Monitoring id
                        woMonitorID = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
                        woMonitorExist = workOrderMonitoringRepository.findOneByWoMonitoringID(woMonitorID);
                    } while (woMonitorExist != null);
                    WorkOrderMonitoring a = new WorkOrderMonitoring();
                    a.setCustomerAtendeeID(dto.getCustomerAttendeeID());
                    a.setPitNumber(dto.getPitNumber());
                    a.setNoPolisi(dto.getNoPolisi());
                    a.setUnitCustomerID(dto.getUnitCustomerID());
                    a.setWoID(dto.getWoID());
                    a.setWoMonitoringID(woMonitorID);
                    a.setWoLastKnownState(WoState.COMPLETE);
                    a.setWoLastKnownStatus(WoStatus.COMPLETE);
                    a.setWoMonitoringCreational(new CreationalSpecification(new Date(), dto.getWoCreationalDTO().getModifiedBy(), new Date(), dto.getWoCreationalDTO().getModifiedBy()));
                    a.setDescription("EVENT COMPLETE PAYMENT WO");
                    a.setReqPayload(new ObjectMapper().writeValueAsString(bodyDto));
                    workOrderMonitoringRepository.save(a);

                    // Jika wo memiliki contract service, maka insert data ke cs monitoring & cust contractservice
                    if (StringUtil.hasValue(dto.getCsID())) {
                        CSMonitoring csMonitoring = new CSMonitoring();
                        csMonitoring.setCsID(dto.getCsID());
                        csMonitoring.setNosin(dto.getWoNoMesin());
                        csMonitoring.setTglTransaksi(new Date());
                        csMonitoring.setLog(null);
                        csMonitoring.setEvent(ContractServiceEvent.COMPLETE_WO);
                        csMonitoring.setReffID(dto.getBookingID() == null ? dto.getWoID() : dto.getBookingID());
                        csMonitoring.setPackageID(null);
                        csMonitoring.setCsMonitoringCreationalSpecification(new CreationalSpecification(new Date(), dto.getWoCreationalDTO().getModifiedBy(), new Date(), dto.getWoCreationalDTO().getModifiedBy()));
                        csMonitoringRepository.save(csMonitoring);

                        // check data existing
                        CustContractService getExistingCustCS = custContractServiceRepository.findOneByCsIDAndNosin(dto.getCsID(), dto.getWoNoMesin());
                        if (getExistingCustCS == null) {
                            // get wsID CS untuk lookup ke tabel jasa CS
                            String wsID = dto.getListJasa().stream()
                                    .filter(v -> v.getIsContractService())
                                    .map(x -> x.getConfigWorkshopServiceID())
                                    .findAny().orElse("").toString();
                            if (StringUtil.hasValue(wsID)) {
//                        		ConfigPackageServicePartPromo getJasaCS = configPackageServicePartPromoRepository.findOneByPromoIDAndReffIDAndSource(dto.getCsID(), wsID, PromoSource.CONTRACT_SERVICE);
                                List<ConfigPackageServicePartPromo> getJasaCS = configPackageServicePartPromoRepository.findAllByPromoIDAndReffIDAndSource(dto.getCsID(), wsID, PromoSource.CONTRACT_SERVICE);
                                if (getJasaCS != null && !getJasaCS.isEmpty()) {
                                    CustContractService custContractService = new CustContractService();
                                    custContractService.setCsID(dto.getCsID());
                                    custContractService.setCustID(dto.getUnitCustomerID());
                                    custContractService.setQuotaDetail(getJasaCS.get(0).getPackageLimit());
                                    custContractService.setCustName(dto.getUnitCustomerName());
                                    custContractService.setNosin(dto.getWoNoMesin());
                                    custContractService.setNopol(dto.getNoPolisi());
//                        			custContractService.setPackageExpired(getJasaCS.getPackageLimit() - 1);
                                    custContractService.setPackageExpired(0);
                                    custContractService.setStatus(com.eksad.ddms.common.util.status.DataStatus.ACTIVE);
                                    custContractService.setCustContractServiceCreational(new CreationalSpecification(new Date(), dto.getWoCreationalDTO().getModifiedBy(), null, null));
                                    custContractServiceRepository.save(custContractService);
                                }
                            }
                        } else {
                            getExistingCustCS.setPackageExpired(getExistingCustCS.getPackageExpired() - 1);
                            getExistingCustCS.setCustContractServiceCreational(new CreationalSpecification(null, null, new Date(), dto.getWoCreationalDTO().getModifiedBy()));
                            custContractServiceRepository.save(getExistingCustCS);
                        }
                    }

                }
            }

            return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseDTO().defaultResponse());
        } catch (Exception e) {
            Logger.getLogger(WorkOrderHystrixService.class.getName()).log(Level.SEVERE, null, e);
            return ResponseEntity.status(HttpStatus.OK).body(
                    new ResponseDTO().failedRespose(String.valueOf(HttpStatus.NOT_FOUND.value()), e.getLocalizedMessage()));
        }
    }

    private void updateWorkOrderData(WorkOrder data, WorkOrderDTO dto) {

        data.setWoID(dto.getWoID());
        data.setAhassID(dto.getAhassID());
        data.setEstimasiMulai(null == data.getEstimasiMulai() ? dto.getEstimasiMulai() : data.getEstimasiMulai());
        data.setEstimasiSelesai(null == data.getEstimasiSelesai() ? dto.getEstimasiSelesai() : data.getEstimasiSelesai());
        data.setNoPolisi(dto.getNoPolisi());
        data.setWoNoRangka(dto.getWoNoRangka());
        data.setWoNoMesin(dto.getWoNoMesin());
        data.setUnitCustomerID(dto.getUnitCustomerID());
        data.setUnitCustomerName(dto.getUnitCustomerName());
        data.setCustomerAttendeeID(dto.getCustomerAttendeeID());
        data.setKmMotor(dto.getKmMotor());
        data.setSuggestedKm(dto.getSuggestedKm());
        data.setFuelMeter(dto.getFuelMeter());
        data.setAlasanDatang(dto.getAlasanDatang());
        data.setAnalisa(dto.getAnalisa());
        data.setTypeJasa(dto.getTypeJasa());
        data.setListJasa(dto.getListJasa() == null ? null : new WorkOrderServiceAssembler().toDomains(dto.getListJasa()));
        data.setTotalHargaJasa(dto.getTotalHargaJasa());
        data.setTotalDiscountJasa(dto.getTotalDiscountJasa());
        data.setTotalWaktuJasa(dto.getTotalWaktuJasa());
        data.setListPart(dto.getListPart() == null ? null : new WorkOrderSparepartAssembler().toDomain(dto.getListPart()));
        data.setTotalHargaSparepart(dto.getTotalHargaSparepart());
        data.setTotalDiscountSparepart(dto.getTotalDiscountSparepart());
        data.setWoLastKnownState(dto.getWoLastKnownState());
        data.setWoLastKnownStatus(dto.getWoLastKnownStatus());
        data.setWoDisclaimerType(dto.getWoDisclaimerType());
        data.setSparepartDibawaCustomer(dto.getSparepartDibawaCustomer());
        data.setConfirmNoTelp(dto.getConfirmNoTelp());
        data.setWoDate(dto.getWoDate());
        data.setQueueNumber(dto.getQueueNumber());
        data.setPitType(dto.getPitType());
        data.setMechanicID(dto.getMechanicID());
        data.setMechanicName(dto.getMechanicName());
        data.setUnitCategoryID(dto.getUnitCategoryID());
        data.setUnitCategoryName(dto.getUnitCategoryName());
        data.setUnitSeriesID(dto.getUnitSeriesID());
        data.setUnitSeriesName(dto.getUnitSeriesName());
        data.setUnitTypeID(dto.getUnitTypeID());
        data.setUnitTypeName(dto.getUnitTypeName());
        data.setUnitTypeColor(dto.getUnitTypeColor());
        data.setSaranMekanik(dto.getSaranMekanik());
        data.setTahunPerakitan(dto.getTahunPerakitan());
        data.setPitNumber(dto.getPitNumber());
        data.setPackageServiceID(dto.getPackageServiceID());
//            data.setPaymentStatus(dto.getPaymentStatus());
        data.setBookingID(dto.getBookingID());
        data.setKeterangan(dto.getKeterangan());
        data.setAlasanHoldWO(dto.getAlasanHoldWO());
        data.setSoID(dto.getSoID());
        data.setListComplaint(dto.getListComplaint() == null ? new HashSet<>() : new ComplaintWorkOrderAssembler().toDomain(dto.getListComplaint()));
//        data.setListPromo(dto.getListPromo() == null ? new HashSet<>() : new PromoWorkOrderAssembler().toDomain(dto.getListPromo()));
        data.setListPromo(dto.getListPromo() == null ? new HashSet<>() : new PromoWorkOrderAssembler().toDomainUpdates(dto.getListPromo(), data.getListPromo()));
        data.getWoCreational().setModifiedAt(new Date());
        data.getWoCreational().setModifiedBy(dto.getWoCreationalDTO().getModifiedBy());
        data.setModifiedTrigger(dto.getModifiedTrigger());
        // handle jika no.faktur dari dto kosong, maka ambil dari no.faktur existing
        data.setInvoice(StringUtil.hasValue(dto.getInvoice()) ? dto.getInvoice() : data.getInvoice());
        data.setNoBukuC2(dto.getNoBukuC2());
        data.setRekomendasiSA(dto.getRekomendasiSA());
        data.setUnitEntrySource(dto.getUnitEntrySource());
        data.setInvoiceUrl(dto.getInvoiceUrl());
    }

    private String defineJenisService(WorkOrderDTO data) {
        String jenisService = "";
        if (data.getListJasa().size() > 1) {
            jenisService = "Multiple Service";
        } else {
            try {
                if (data.getListJasa().get(0).getConfigWorkshopServiceID().startsWith("CWS")) {
                    jenisService = configWorkshopServiceRepository.findOneByConfigWorkshopServiceID(data.getListJasa().get(0).getConfigWorkshopServiceID()).getConfigworkshopserviceName();
                } else {
                    jenisService = wsRepository.findOneByWorkshopServiceID(data.getListJasa().get(0).getConfigWorkshopServiceID()).getWorkshopServiceName();
                }
            } catch (Exception e) {
                jenisService = "";
            }

        }
        return jenisService;
    }

    private void insertClaimKPB(WorkOrderDTO workOrder, WorkOrderServiceDTO woService) {
        CustomerAttendee cust = custAttendeeRepository.findOneByCustomerAttendeeID(workOrder.getCustomerAttendeeID());

        ClaimKPBDTO a = new ClaimKPBDTO();
        a.setClaimkpbID("KPB-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase());
        a.setWoID(workOrder.getWoID());
        a.setAlamat(cust == null ? null : cust.getAddress());
        a.setKeterangan(workOrder.getKeterangan());
        a.setKmService(workOrder.getKmMotor());
        a.setKodeMesin(workOrder.getWoNoRangka());
        a.setNamaPemilik(workOrder.getUnitCustomerName() == null ? " " : workOrder.getUnitCustomerName());
        a.setNoMesin(workOrder.getWoNoMesin() == null ? null : workOrder.getWoNoMesin().toUpperCase());
        a.setTanggalService(workOrder.getWoDate());
        a.setAhassID(workOrder.getAhassID());
        a.setIsClaim(Boolean.FALSE);
        a.setNominalClaim(woService.getHarga());
        a.setStatus("DRAFT");
        a.setKodeBuku("000");
        a.setNomorBuku("123");
        a.setTanggalPengajuan(workOrder.getWoDate());
        a.setClaimKpbCreationalDTO(new CreationalSpecificationDTO(new Date(), workOrder.getWoCreationalDTO().getModifiedBy(), null, null));

//      Set Tanggal Pembelian dari mst_unitcustomer
        UnitCustomer uc = unitCustomerRepository.findOneByUnitCustomerID(workOrder.getUnitCustomerID());
        if (uc != null) {
            if (uc.getTanggalPembelian() != null) {
                a.setTanggalPembelian(uc.getTanggalPembelian());
                a.setSourceTanggalPembelian("UNIT_CUST");
            }
        }

        bukuKPB(a);
        WorkshopService service = wsRepository.findOneByWorkshopServiceID(woService.getConfigWorkshopServiceID());
        if ("ASS 1".equalsIgnoreCase(service.getServiceCategory())) {
            a.setJenisKPB(TypeKPB.KPB_1);
        } else if ("ASS 2".equalsIgnoreCase(service.getServiceCategory())) {
            a.setJenisKPB(TypeKPB.KPB_2);
        } else if ("ASS 3".equalsIgnoreCase(service.getServiceCategory())) {
            a.setJenisKPB(TypeKPB.KPB_3);
        } else if ("ASS 4".equalsIgnoreCase(service.getServiceCategory())) {
            a.setJenisKPB(TypeKPB.KPB_4);
        } else {
            a.setJenisKPB(TypeKPB.NON_KPB);
        }

        try {
            ResponseEntity<ResponseDTO> response = restTemplate.exchange(
                    claim_url
                            + ClaimKPBURI.POST_CLAIMKPB.getUri(),
                    HttpMethod.POST,
                    new HttpEntity<>(a, RequestUtil.getPreFormattedRequestWithUserPassword().getHeaders()),
                    ResponseDTO.class);
            System.out.println("[INSERT KPB - POST] = " + a.getWoID() + " " + response.getBody().getMessage());
        } catch (Exception e) {
            Logger.getLogger(WorkOrderHystrixService.class.getName()).log(Level.SEVERE, "Error insert Claim KPB", e);
        }
    }

    private void bukuKPB(ClaimKPBDTO a) {
        String machineNumber = a.getNoMesin();
        if (StringUtil.hasValue(machineNumber)) {
            String[] split = machineNumber.split(" ");
            if (split.length > 0) {
                String engineCode = split[0].toUpperCase();
                KartuKPB kartuKPB = findKartuKPBByEngineCode(engineCode);
                if (kartuKPB.getKodeKartu() != null) {
                    a.setKodeKartuKPB(kartuKPB.getKodeKartu());
                }
                System.out.println("[INSERT KPB - KODE KARTU] = " + a.getWoID() + " " + a.getKodeKartuKPB());
            }
        }
    }

    private KartuKPB findKartuKPBByEngineCode(String engineCode) {
        List<KartuKPB> list = kartuKPBRepository.findAllByEngineCodeAndDataStatus(engineCode, com.eksad.ddms.common.util.status.DataStatus.ACTIVE);
        if (list.size() > 0) {
            return list.get(0);
        } else {
            return new KartuKPB();
        }
    }

    private void insertClaimC2(WorkOrderDTO workOrder, List<WorkOrderSparepartDTO> p) {
        //Sort part berdasarkan harga tertinggi
        Comparator<WorkOrderSparepartDTO> compareByPrice = (WorkOrderSparepartDTO o1, WorkOrderSparepartDTO o2) -> o1.getHarga().compareTo(o2.getHarga());
        Collections.sort(p, compareByPrice.reversed());

        WorkOrderSparepartDTO woSparepart = p.get(0);

        ClaimC2DTO a = new ClaimC2DTO();
        a.setClaimC2ID(updateClaimC2Number(workOrder.getAhassID(), "C2-J10", workOrder.getWoCreationalDTO().getModifiedBy()));
        a.setNoWO(workOrder.getWoID());
        a.setNoRangka(workOrder.getWoNoRangka());
        a.setNoMesin(workOrder.getWoNoMesin() == null ? null : workOrder.getWoNoMesin().toUpperCase());
        a.setAhassID(workOrder.getAhassID());
        a.setStatus("DRAFT");
        a.setQty(woSparepart.getQty());
        a.setClaimC2DTOs(new ArrayList<>());
        a.setClaimC2CreationalDTO(new CreationalSpecificationDTO(new Date(), workOrder.getWoCreationalDTO().getModifiedBy(), null, null));
        a.setNoBukuService(workOrder.getNoBukuC2());

        PartDTO part = findPartById(woSparepart.getPartID());
        a.setPartNumber(woSparepart.getPartID());
        if (part != null) {
            a.setPartDescription(part.getPartDescription());
            a.setHet(part.getHet());
        }
        // Take out part Utama dari list
        List<WorkOrderSparepartDTO> filteredPart = p.stream().filter(fp -> !fp.getPartID().equalsIgnoreCase(woSparepart.getPartID())).collect(Collectors.toList());
        a.setClaimC2DTOs(partTerkaitClaimC2(filteredPart, a.getClaimC2ID()));

        try {
            ResponseEntity<ResponseDTO> response = restTemplate.exchange(
                    claim_url
                            + ClaimC2URI.POST_CLAIM_C2.getUri(),
                    HttpMethod.POST,
                    new HttpEntity<>(a, RequestUtil.getPreFormattedRequestWithUserPassword().getHeaders()),
                    ResponseDTO.class);
        } catch (Exception e) {
            Logger.getLogger(WorkOrderHystrixService.class.getName()).log(Level.SEVERE, "Error insert Claim C2", e);
        }
    }

    public String updateClaimC2Number(String ahassID, String code, String userID) {
        String receivingNumber;
        ResponseEntity<String> response = restTemplate.exchange(
                DDMS_H2_SERVICE_SLAVE
                        + IntegrasiURI.UPDATE_GENERATE_SEQUENCE.getUri(),
                HttpMethod.GET,
                RequestUtil.getPreFormattedRequestWithUserPassword(),
                String.class, ahassID, code, userID);
        receivingNumber = response.getBody() == null ? "" : response.getBody();
        return receivingNumber;
    }

    private PartDTO findPartById(String partID) {
        if (StringUtil.hasValue(partID)) {
            ResponseEntity<ResponsePartGetDTO> response = restTemplate.exchange(
                    DDMS_H2_SERVICE_SLAVE
                            + PartURI.PART_GET_BY_ID.getUri(),
                    HttpMethod.GET,
                    RequestUtil.getPreFormattedRequestWithUserPassword(),
                    ResponsePartGetDTO.class,
                    partID);
            return response.getBody().getData() == null ? new PartDTO() : response.getBody().getData();
        }
        return new PartDTO();
    }

    private List<ClaimC2ItemDTO> partTerkaitClaimC2(List<WorkOrderSparepartDTO> p, String claimC2ID) {
        List<ClaimC2ItemDTO> listItem = new ArrayList<>();
        for (WorkOrderSparepartDTO woSparepart : p) {
            ClaimC2ItemDTO a = new ClaimC2ItemDTO();
            a.setClaimC2ItemID(UUID.randomUUID().toString().substring(0, 8).toUpperCase());
            a.setClaimC2ID(claimC2ID);
            a.setClaimPartCode(woSparepart.getPartID());
            PartDTO part = findPartById(woSparepart.getPartID());
            if (part != null) {
                a.setClaimPartDesc(part.getPartDescription());
                a.setHet(part.getHet());
            }
            a.setJenisPart("TERKAIT");
            a.setJenisPenggantian(null);
            a.setOngkosKerja(null);
            a.setClaimPartQty(woSparepart.getQty());
            a.setJasa(null);
            a.setVoucher(null);
            a.setBiayaAdmin(null);
            a.setTotal(null);
            listItem.add(a);
        }
        return listItem;
    }

}