package com.sifang.modules.customer.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.customer.constant.YueXiuConstants;
import com.sifang.modules.customer.dao.CrmCustomerEntryRentManagementDao;
import com.sifang.modules.customer.dao.CustomerEntryDao;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.customer.form.OlDocumentFarmGainsDto;
import com.sifang.modules.customer.form.PrjDocumentStatusDto;
import com.sifang.modules.customer.form.QueryDocumentRes;
import com.sifang.modules.customer.form.QueryRentListRes;
import com.sifang.modules.sunshine.SystemSetting.dao.PlanMaterialEntryDao;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.DbKey;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class CrmCustomerEntryRentManagementService  extends BaseService {

    @Autowired
    private CrmCustomerEntryRentManagementDao rentManagementDao;

    @Autowired
    private OperatingLeaseService operatingLeaseService;

    @Autowired
    private CustomerEntryDao customerEntryDao;


    @Autowired
    private PlanMaterialEntryDao planMaterialEntryDao;

    @Value("${yx.setting}")
    private String YX;


    /**
     * 获取列表数据
     */
    public String getPageData(LayuiPage page, Map<String, String> map, Operator operator) {
        logger.info("getCustomerEntryRentListData, map={}", map);
        page.setData(rentManagementDao.findPageData(page, map, operator));
        page.setCount(rentManagementDao.findPageCount(map, operator));
        return page.renderJson();
    }

    //农户收益查询
    public List<QueryRentListRes> getRentList(String  synchronizationType ,String dueDateFrom,String dueDateTo, String partnersContractNumber){
        Map<String, Object> map = new HashMap<>();
        List<Object> bodyData=new ArrayList<>();
        Map<String,Object> map1=new HashMap<>();
        OlDocumentFarmGainsDto olDocumentFarmGainsDto = new OlDocumentFarmGainsDto();
        olDocumentFarmGainsDto.setSynchronizationType(synchronizationType);
        if ("FULL".equals(synchronizationType)){
            olDocumentFarmGainsDto.setDueDateFrom(dueDateFrom);//应收日期从
            olDocumentFarmGainsDto.setDueDateTo(dueDateTo);//应收日期到
        }
        if (StringUtil.isNotBlank(partnersContractNumber)) {
            olDocumentFarmGainsDto.setPartnersContractNumber(partnersContractNumber);
        }
        map1.put("olDocumentFarmGainsDto",olDocumentFarmGainsDto);
        bodyData.add(map1);
        map.put("body",bodyData);
        Map<String, Object> head = new HashMap<>();
        head.put("errorCode", "01");
        head.put("serialNumber", UUID.randomUUID().toString());
        head.put("systemId", YueXiuConstants.CLIENT_ID);
        head.put("transactionCode",YueXiuConstants.TRANSACTION_CODE_RENT+YX);
        head.put("transactionTime", DateUtils.formatDate(new Date(),"yyyyMMdd HH:mm:ss"));
        head.put("version",1);
        map.put("head",head);
        Gson gson=new Gson();
        logger.info("农户收益查询  getFullRentList json:{}",gson.toJson(map));
        JSONObject jieMap = operatingLeaseService.clientPostZYMap(map,YueXiuConstants.QUERY_INCOME);
        logger.info("农户收益查询 getFullRentList -------返回结果：{}", jieMap);
        JSONArray reqMap = jieMap.getJSONArray("body");
        JSONObject re = reqMap.getJSONObject(0);
        if ("S".equals(re.get("type"))) {
            String cashflowList = re.getString("cashflowList");
            List<QueryRentListRes> queryRentListResList =  gson.fromJson(cashflowList, new TypeToken<ArrayList<QueryRentListRes>>() {}.getType());
            return queryRentListResList;
        }else {
            throw new IllegalArgumentException("农户收益查询失败!失败原因："+re.get("message"));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void dealRentList(String  synchronizationType,String dueDateFrom,String dueDateTo, String contractNumber) {
        List<QueryRentListRes> fullRentList = getRentList(synchronizationType, dueDateFrom, dueDateTo, contractNumber);
        logger.info(">>>>>>>>>>dealRentList  res：{}", new Gson().toJson(fullRentList));
        for (QueryRentListRes queryRentListRes : fullRentList) {
            try {
                dealRentInfo(queryRentListRes);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void dealRentInfo(QueryRentListRes queryRentListRes) {
        boolean flag = Db.queryLong(" select count(1) from crm_customer_entry_rent_management where  cf_id = ?", queryRentListRes.getCfId()) > 0;
        String partnersContractNumber = queryRentListRes.getPartnersContractNumber();
        Record record = Db.findFirst(" SELECT archive_no, capacity ,station_name,office_name,grid_time from  crm_yk_customer_entry where  partners_contract_number =  ?", partnersContractNumber);
        String entryId = Db.queryStr(" select entry_id from crm_customer_incoming_application where partners_contract_number = ?", partnersContractNumber);
        String archiveNo = "";
        String capacity = "";
        String officeName = "";
        String stationName = "";
        Date mergeTime = null;
        if (record != null) {
            archiveNo = record.getStr("archive_no");//电站编码
            capacity = record.getStr("capacity");//装机容量
            officeName = record.getStr("office_name");//代理商名称
            stationName = record.getStr("station_name");//电站名称
            mergeTime = record.getDate("merge_time");//并网时间
        } else if (StringUtils.isNotBlank(entryId)) {
            CustomerEntry entry = customerEntryDao.get(entryId);
            archiveNo = entry.getPowerStationCode();
            capacity = entry.getActualCapacity().stripTrailingZeros().toPlainString();
            officeName = entry.getTraderName();
            stationName = CrmUtils.getStationName(entry);
            mergeTime = entry.getMergeTime();
        }
        //期数
        String period = queryRentListRes.getTimes();
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
        //应付日期
        Date dueTime = null;
        String dueDate = queryRentListRes.getDueDate();
        if (StringUtils.isNotBlank(dueDate)) {
            try {
                Date parse = inputFormat.parse(dueDate);
                dueTime = outputFormat.parse(outputFormat.format(parse));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        //应付金额
        String dueMoney = queryRentListRes.getDueAmount();
        //已付日期
        Date receiveDate = null;
        String paidTime = queryRentListRes.getReceivedDate();
        if (StringUtils.isNotBlank(paidTime)) {
            try {
                Date parse = inputFormat.parse(paidTime);
                receiveDate = outputFormat.parse(outputFormat.format(parse));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        String cfId = queryRentListRes.getCfId();
        if (StringUtils.isNotBlank(archiveNo)) {
            if (!flag) {
                Db.update(" insert into crm_customer_entry_rent_management (id,power_station_code,partners_contract_number,office_name," +
                        " station_name,merge_time,capacity,period,due_time,due_money,paid_time,cf_id )" +
                        "  values (?,?,?,?,?,?,?,?,?,?,?,?)", IdGen.uuid(), archiveNo, partnersContractNumber, officeName, stationName, mergeTime, capacity, period, dueTime, dueMoney, receiveDate, cfId);
            } else {
                Db.update(" update crm_customer_entry_rent_management set period = ? ,due_time = ? ,due_money = ? ,paid_time = ?  where cf_id = ? ", period, dueTime, dueMoney, receiveDate, cfId);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void sysPaidDate() {
        List<Record> list = Db.find(" SELECT DISTINCT(a.`partners_contract_number`) AS number " +
                "FROM crm_customer_entry_rent_management a " +
                "WHERE a.`paid_time` IS NULL");
        for (Record r : list) {
            String number = r.getStr("number");
            try {
                Record record = Db.findFirst(" SELECT a.`partners_contract_number`, MIN(a.`due_time`) AS beftert, MAX(a.`due_time`) AS aftert " +
                        "FROM crm_customer_entry_rent_management a " +
                        "WHERE a.`paid_time` IS NULL AND a.`partners_contract_number` = ?", number);
                Date startDat = record.getTimestamp("beftert");
                startDat = new Date(startDat.getTime()-DateUtils.MILLIS_PER_DAY);
                Date endDat = record.getTimestamp("aftert");
                endDat = new Date(endDat.getTime()+DateUtils.MILLIS_PER_DAY);
                List<QueryRentListRes> fullRentList = getRentList("FULL",
                        DateUtils.formatDate(startDat, "yyyyMMdd"), DateUtils.formatDate(endDat, "yyyyMMdd"), number);
                for (QueryRentListRes queryRentListRes : fullRentList) {
                    dealRentInfo(queryRentListRes);
                }
            }catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public void  getYouKuaStationData(){
        List<Record> records = Db.use(DbKey.DB_YOUKUA).find("SELECT DISTINCT m.partners_contract_number,a.archive_no,a.capacity,a.rpovince_name,a.city_name ,a.county_name, " +
                " e.sales_name,p.insurance_money,a.station_name,a.office_name,a.address, " +
                " CASE p.`status` WHEN 0 THEN '等待请款' WHEN 1 THEN '审批中'  WHEN 2 THEN '驳回'  WHEN 3 THEN '完成'  WHEN 4 THEN '已放款' WHEN 8 THEN '等待放款'  END AS status, " +
                " DATE_ADD(p.create_time,INTERVAL 13 HOUR) as create_time, DATE_ADD(p.update_time,INTERVAL 13 HOUR) as update_time,DATE_ADD(a.grid_time,INTERVAL 13 HOUR) as grid_time " +
                " FROM bus_payment p LEFT JOIN bus_archive a ON a.id = p.archive_id  LEFT JOIN js_yx_materia_config m ON m.archive_no = a.archive_no " +
                " LEFT JOIN bus_archive_sales AS e ON e.archive_id = a.id   WHERE p.del_flg = 0  and p.`status`=4 ");
        logger.info("youkua station data size:{}",records.size());
        for (Record record : records) {
            String partnersContractNumber = record.getStr("partners_contract_number");
            boolean flag = Db.queryLong(" select count(1) from crm_yk_customer_entry where partners_contract_number = ? ",partnersContractNumber)>0;
            if (!flag){
                Db.update(" INSERT INTO `crm_yk_customer_entry`(`id`, `partners_contract_number`, `archive_no`, `capacity`, `province`, `city`, `area`, `address`, `sales_name`, `insurance_money`, `station_name`, `office_name`, `status`, `create_time`, `update_time`, `grid_time`) " +
                        " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",IdGen.uuid(), partnersContractNumber,record.getStr("archive_no"),
                        record.getStr("capacity"),record.getStr("rpovince_name"),record.getStr("city_name"),record.getStr("county_name"),
                        record.getStr("address"),record.getStr("sales_name"),record.getBigDecimal("insurance_money"),record.getStr("station_name"),
                        record.getStr("office_name"),record.getStr("status"),record.getDate("create_time"),record.getDate("update_time"),
                        record.getDate("grid_time"));
            }
        }
    }

}
