package com.viettel.campaign.job;

import com.viettel.campaign.model.ccms_full.Campaign;
import com.viettel.campaign.model.ccms_full.Customer;
import com.viettel.campaign.model.ccms_full.CustomerTime;
import com.viettel.campaign.model.ccms_full.ProcessConfig;
import com.viettel.campaign.service.CampaignService;
import com.viettel.campaign.service.CustomerService;
import com.viettel.campaign.service.CustomerTimeService;
import com.viettel.campaign.service.ProcessConfigService;
import com.viettel.campaign.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author hanv_itsol
 * @project campaign
 */

@Slf4j
public class CampaignJob {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    private static final String CUSTOMER_INACTIVE_DUARATION =  "CUSTOMER_INACTIVE_DUARATION";
    private static final String CRON_EXPRESSION_CHECK_START =  "CRON_EXPRESSION_CHECK_START";
    private static final String CRON_EXPRESSION_CHECK_END =  "CRON_EXPRESSION_CHECK_END";

    @Autowired
    private ProcessConfigService processConfigService;

    @Autowired
    private CampaignService campaignService;

    @Autowired
    private CustomerTimeService customerTimeService;

    @Autowired
    private CustomerService customerService;

//    @Scheduled(fixedRate = 5000)
//    @Transactional( propagation = Propagation.REQUIRED)
    public void process() {
        log.info(Thread.currentThread().getName() + " The Task executed at " + dateFormat.format(new Date()));
        List<ProcessConfig> list = processConfigService.findAll();

        list.parallelStream().forEach(p -> {
            boolean isExecute = DateTimeUtil.isRun(p.getConfigValue(), p.getLastProcess());
            switch (p.getConfigCode()){
                case CUSTOMER_INACTIVE_DUARATION:
                    if(isExecute){
                        List<Customer> customers = customerService.findAllByCondition(p.getSiteId(), new Date());
                        updateCustomer(customers);
                        updateCustomerTime(customers);
                        log.info("Cap nhat thoi gian thuc hien tien trinh cho siteId ... #{}", p.getSiteId());
                        p.setLastProcess(new Date());
                        processConfigService.update(p);
                    }
                    break;
                case CRON_EXPRESSION_CHECK_START:
                    // process
                    if(isExecute){
                        List<Long> status = new ArrayList<>();
                        status.add(1L);
                        status.add(1L);
                        List<Campaign> campaigns = campaignService.findCampaignByCompanySiteIdAndStartTimeIsLessThanEqualAndStatusIn(p.getSiteId(), new Date(), status);
                        campaigns.parallelStream().forEach(campaign -> {
                            log.info("Chuyen trang thai chien dich ... #{} ... tu Du thao sang Trien khai", campaign.getCampaignId());
                            campaign.setProcessStatus(1);
                            campaign.setStatus(2L);
                            campaign.setCampaignStart(new Date());
                            campaignService.updateProcess(campaign);
                        });

                        log.info("Cap nhat thoi gian thuc hien tien trinh cho siteId ... #{}", p.getSiteId());
                        p.setLastProcess(new Date());
                        processConfigService.update(p);
                    }
                    break;
                case CRON_EXPRESSION_CHECK_END:
                    // process
                    if(isExecute){
                        List<Long> status = new ArrayList<>();
                        status.add(2L);
                        status.add(3L);
                        List<Campaign> campaigns = campaignService.findCampaignByCompanySiteIdAndEndTimeIsLessThanEqualAndStatusIn(p.getSiteId(), new Date(), status);
                        campaigns.parallelStream().forEach(campaign -> {
                            log.info("Chuyen trang thai chien dich ... #{} ... sang Ket thuc", campaign.getCampaignId());
                            campaign.setStatus(4L);
                            campaign.setCampaignEnd(new Date());
                            campaignService.updateProcess(campaign);
                        });

                        log.info("Cap nhat thoi gian thuc hien tien trinh cho siteId ... #{}", p.getSiteId());
                        p.setLastProcess(new Date());
                        processConfigService.update(p);
                    }
                    break;
                default:
                    // update last check time
            }
        });


    }

    private void updateCustomer(List<Customer> customers){
        customers.parallelStream().forEach(c -> {
            log.info("Cap nhat trang thai khoa cua KH ... #{}", c.getCustomerId());
            c.setIpccStatus("active");
            customerService.update(c);
        });
    }

    private void updateCustomerTime(List<Customer> customers){
        customers.parallelStream().forEach(customer -> {
            // find all customer_time by customerId
            List<CustomerTime> customerTimes = customerTimeService.findByCustomerId(customer.getCustomerId());
            customerTimes.parallelStream().forEach(customerTime -> {
                log.info("Cap nhat Customer time cua KH ... #{}", customerTime.getCustomerId());
                customerTime.setStatus(2);
                customerTime.setUpdateTime(new Date());
                customerTimeService.update(customerTime);
            });
        });
    }


}
