package com.sifang.modules.supply.stock.service;

import com.google.common.collect.Maps;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.customer.excel.MaterialExcel;
import com.sifang.modules.supply.order.dao.MaterialApplyDetailDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverDetailDao;
import com.sifang.modules.supply.order.service.DeliverOrderService;
import com.sifang.modules.supply.stock.excel.AllOrderExcel;
import com.sifang.modules.supply.stock.excel.DeliverOrderExcel;
import com.sifang.modules.supply.stock.excel.SupplyDeliverOrderExcel;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.StringUtil;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.excel.ExportExcel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author hongzq
 */
@Service
public class ExportService {

    @Autowired
    MaterialDeliverDao deliverDao;
    @Autowired
    MaterialDeliverDetailDao deliverDetailDao;
    @Autowired
    MaterialApplyDetailDao applyDetailDao;

    private Logger logger = LoggerFactory.getLogger(getClass());

    public void exportSupplyOrder(Map<String, String> map, HttpServletResponse response) throws IOException {
        List<Record> list = deliverDao.deliverOrderList(null, map);
        List<String> ids = new ArrayList<>();
        for (Record record : list) {
            ids.add(record.getStr("id"));
        }
        List<Record> details = deliverDetailDao.findDetailsByOrderIds(ids);
        Map<String, List<Record>> detailsMap = new HashMap<>();
        for (Record detail : details) {
            List<Record> detailList = detailsMap.get(detail.getStr("main_id"));
            if (detailList != null) {
                detailList.add(detail);
            } else {
                List<Record> arr = new ArrayList<>();
                arr.add(detail);
                detailsMap.put(detail.getStr("main_id"), arr);
            }
        }
        List<DeliverOrderExcel> orderExcels = new ArrayList<>();
        int sort = 1;
        for (Record rd : list) {
            List<Record> materials = detailsMap.get(rd.getStr("id"));
            for (Record material : materials) {
                DeliverOrderExcel deliverOrderExcel = new DeliverOrderExcel();
                deliverOrderExcel.setSort(String.valueOf(sort));
                deliverOrderExcel.setNumber(rd.getStr("number"));
                deliverOrderExcel.setStatus(transDeliverStatus(rd.getStr("status")));
                deliverOrderExcel.setOutWarehouseName(rd.getStr("outWarehouseName"));
                deliverOrderExcel.setDeliver_method_name(rd.getStr("deliver_method_name"));
                deliverOrderExcel.setPlace_name(rd.getStr("place_name"));
                deliverOrderExcel.setInWarehouseName(rd.getStr("inWarehouseName"));
                deliverOrderExcel.setPerson_in_charge(rd.getStr("person_in_charge"));
                deliverOrderExcel.setMobile(rd.getStr("mobile"));
                deliverOrderExcel.setAddress(rd.getStr("address"));
                deliverOrderExcel.setRelate_no(rd.getStr("relate_no"));
                deliverOrderExcel.setDeliver_remark(rd.getStr("deliver_remark"));
                deliverOrderExcel.setRemarks(rd.getStr("remarks"));
                deliverOrderExcel.setCreate_time(rd.getDate("create_time"));
                deliverOrderExcel.setDeliver_time(rd.getDate("deliver_time"));
                deliverOrderExcel.setMaterialCode(material.getStr("code"));
                deliverOrderExcel.setMaterialTypeName(material.getStr("materialTypeName"));
                deliverOrderExcel.setMaterialGroupName(material.getStr("materialGroupName"));
                deliverOrderExcel.setMaterialRemarks(material.getStr("remarks"));
                deliverOrderExcel.setUnit(material.getStr("unit"));
                deliverOrderExcel.setApply_amount(material.getBigDecimal("apply_amount"));
                deliverOrderExcel.setOut_amount(material.getBigDecimal("out_amount"));
                orderExcels.add(deliverOrderExcel);
                sort++;
            }
        }
        String fileName = map.get("name") + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
        new ExportExcel(map.get("name"), DeliverOrderExcel.class)
                .setDataList(orderExcels)
                .write(response, fileName)
                .dispose();
    }

    public void exportSupplyDeliverOrder(Map<String, String> map, HttpServletResponse response) throws IOException {
        List<Record> list = deliverDao.deliverOrderList(null, map);
        List<String> ids = new ArrayList<>();
        for (Record record : list) {
            ids.add(record.getStr("id"));
        }
        List<Record> details = deliverDetailDao.findDetailsByOrderIds(ids);
        Map<String, List<Record>> detailsMap = new HashMap<>();
        for (Record detail : details) {
            List<Record> detailList = detailsMap.get(detail.getStr("main_id"));
            if (detailList != null) {
                detailList.add(detail);
            } else {
                List<Record> arr = new ArrayList<>();
                arr.add(detail);
                detailsMap.put(detail.getStr("main_id"), arr);
            }
        }
        List<SupplyDeliverOrderExcel> orderExcels = new ArrayList<>();
        int sort = 1;
        for (Record rd : list) {
            List<Record> materials = detailsMap.get(rd.getStr("id"));
            for (Record material : materials) {
                SupplyDeliverOrderExcel deliverOrderExcel = new SupplyDeliverOrderExcel();
                deliverOrderExcel.setSort(String.valueOf(sort));
                deliverOrderExcel.setNumber(rd.getStr("number"));
                deliverOrderExcel.setStatus(transDeliverStatus(rd.getStr("status")));
                deliverOrderExcel.setOutWarehouseName(rd.getStr("outWarehouseName"));
                deliverOrderExcel.setDeliver_method_name(rd.getStr("deliver_method_name"));
                deliverOrderExcel.setPlace_name(rd.getStr("place_name"));
                deliverOrderExcel.setInWarehouseName(rd.getStr("inWarehouseName"));
                deliverOrderExcel.setPerson_in_charge(rd.getStr("person_in_charge"));
                deliverOrderExcel.setMobile(rd.getStr("mobile"));
                deliverOrderExcel.setAddress(rd.getStr("address"));
                deliverOrderExcel.setApplyOrderNumber(rd.getStr("applyOrderNumber"));
                deliverOrderExcel.setDeliver_remark(rd.getStr("deliver_remark"));
                deliverOrderExcel.setRemarks(rd.getStr("remarks"));
                deliverOrderExcel.setCreate_time(rd.getDate("create_time"));
                deliverOrderExcel.setDeliver_time(rd.getDate("deliver_time"));
                deliverOrderExcel.setMaterialCode(material.getStr("code"));
                deliverOrderExcel.setMaterialTypeName(material.getStr("materialTypeName"));
                deliverOrderExcel.setMaterialGroupName(material.getStr("materialGroupName"));
                deliverOrderExcel.setMaterialRemarks(material.getStr("remarks"));
                deliverOrderExcel.setUnit(material.getStr("unit"));
                deliverOrderExcel.setApply_amount(material.getBigDecimal("apply_amount"));
                deliverOrderExcel.setOut_amount(material.getBigDecimal("out_amount"));
                orderExcels.add(deliverOrderExcel);
                sort++;
            }
        }
        String fileName = "发货单管理" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
        new ExportExcel("发货单管理", SupplyDeliverOrderExcel.class)
                .setDataList(orderExcels)
                .write(response, fileName)
                .dispose();
    }
    
    private String transDeliverStatus(String status){
        switch (status) {
            case "1":
                return "待发货";
            case "2":
                return "待收货";
            case "3":
                return "已撤销";
            case "4":
                return "仓库打回";
            case "5":
                return "待入账";
            case "6":
                return "入账未通过";
            case "7":
                return "已完成";
            default:
                return "";
        }
    }

    public void exportAllOrder(Map<String, String> map, HttpServletResponse response) throws IOException {
        User user = UserUtils.getUser();
        List<Record> list = deliverDao.allOrderList(null, map);
        List<String> applyOrderIds = new ArrayList<>();
        List<String> deliverOrderIds = new ArrayList<>();
        //物料明细 有发货单就取发货单的否则取申请单的
        for (Record record : list) {
            if (StrKit.isBlank(record.getStr("deliverOrderId"))) {
                applyOrderIds.add(record.getStr("applyOrderId"));
            } else {
                deliverOrderIds.add(record.getStr("deliverOrderId"));
            }
        }
        Map<String, List<Record>> applyOrderDetailMap = Maps.newHashMap();
        if(applyOrderIds.size()>0){
            List<Record> applyOrderDetails = applyDetailDao.listByApplyIds(applyOrderIds);
            applyOrderDetailMap = changeToMap(applyOrderDetails, "apply_id");
        }

        List<Record> deliverOrderDetails = deliverDetailDao.findDetailsByOrderIds(deliverOrderIds);
        Map<String, List<Record>> deliverOrderDetailMap = changeToMap(deliverOrderDetails, "main_id");

        List<AllOrderExcel> orderExcels = new ArrayList<>();
        int sort = 1;
        for (Record rd : list) {
            List<Record> materials;
            if(StrKit.isBlank(rd.getStr("deliverOrderId"))){
                materials = applyOrderDetailMap.get(rd.getStr("applyOrderId"));
            }else {
                materials = deliverOrderDetailMap.get(rd.getStr("deliverOrderId"));
            }
            if(materials.size()<1 ){
                logger.info("订单编号{}，下无物料明细数据",rd.getStr("deliverOrderNumber"));
            }
            for (Record material : materials) {
                AllOrderExcel allOrderExcel = new AllOrderExcel();
                allOrderExcel.setSort(String.valueOf(sort));
                allOrderExcel.setApplyOrderNumber(rd.getStr("applyOrderNumber"));
                allOrderExcel.setProject_code(rd.getStr("project_code"));
                allOrderExcel.setMergeStatus(transMergeStatus(rd.getStr("mergeStatus")));
                allOrderExcel.setDeliver_name(rd.getStr("deliver_name"));
                allOrderExcel.setDeliver_method_name(rd.getStr("deliver_method_name"));
                allOrderExcel.setOutWarehouseName(rd.getStr("outWarehouseName"));
                if (User.USER_TYPE_YYS.equals(user.getUserType()) || User.USER_TYPE_PTYG.equals(user.getUserType())) {
                    allOrderExcel.setPlaceName(rd.getStr("applyOrderTrader"));
                } else {
                    allOrderExcel.setPlaceName(rd.getStr("applyOrderCreator"));
                }
                allOrderExcel.setInWarehouseName(rd.getStr("inWarehouseName"));
                allOrderExcel.setPerson_in_charge(rd.getStr("person_in_charge"));
                allOrderExcel.setMobile(rd.getStr("mobile"));
                allOrderExcel.setAddress(rd.getStr("address"));
                allOrderExcel.setDeliverOrderNumber(rd.getStr("deliverOrderNumber"));
                allOrderExcel.setDeliver_remark(rd.getStr("deliver_remark"));
                allOrderExcel.setApplyOrderRemarks(rd.getStr("applyOrderRemarks"));
                allOrderExcel.setApplyOrderCreateTime(rd.getDate("applyOrderCreateTime"));
                allOrderExcel.setOrder_time(rd.getDate("order_time"));
                allOrderExcel.setAuditTime(rd.getDate("auditTime"));
                allOrderExcel.setDeliver_time(rd.getDate("deliver_time"));
                allOrderExcel.setReceive_time(rd.getDate("receive_time"));
                allOrderExcel.setAudit_time(rd.getDate("audit_time"));


                allOrderExcel.setMaterialCode(material.getStr("code"));
                allOrderExcel.setMaterialTypeName(material.getStr("materialTypeName"));
                allOrderExcel.setMaterialGroupName(material.getStr("materialGroupName"));
                allOrderExcel.setMaterialRemarks(material.getStr("remarks"));
                allOrderExcel.setUnit(material.getStr("unit"));
                allOrderExcel.setApply_amount(material.getBigDecimal("apply_amount"));
                allOrderExcel.setOut_amount(material.getBigDecimal("out_amount"));
                orderExcels.add(allOrderExcel);
                sort++;
            }
        }
        String fileName = "订单查询" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
        new ExportExcel("订单查询", AllOrderExcel.class)
                .setDataList(orderExcels)
                .write(response, fileName)
                .dispose();
    }

    private String transMergeStatus(String mergeStatus){
        if (mergeStatus.contains("apply")) {
            return transApplyStatus(mergeStatus.split("-")[1]);
        } else if (mergeStatus.contains("deliver")) {
            return transDeliverStatus(mergeStatus.split("-")[1]);
        }
        return "";
    }

    private String transApplyStatus(String status){
        switch (status) {
            case "1":
                return "待业务员审批";
            case "2":
                return "待工程部审批";
            case "3":
                return "待运管部审批";
            case "4":
                return "审批未通过";
            case "5":
                return "待匹配";
            default:
                return "";
        }
    }

    private Map<String, List<Record>> changeToMap(List<Record> details, String key) {
        Map<String, List<Record>> detailsMap = new HashMap<>();
        for (Record detail : details) {
            List<Record> detailList = detailsMap.get(detail.getStr(key));
            if (detailList != null) {
                detailList.add(detail);
            } else {
                List<Record> arr = new ArrayList<>();
                arr.add(detail);
                detailsMap.put(detail.getStr(key), arr);
            }
        }
        return detailsMap;
    }

}
