package com.sifang.modules.changes.controller;

import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.changes.dao.CrmCustomerEntryChangeDesignDetailDao;
import com.sifang.modules.changes.entity.CrmCustomerEntryChangeDesign;
import com.sifang.modules.changes.service.CustomerEntryChangeDesignComponentService;
import com.sifang.modules.changes.service.CustomerEntryChangeDesignService;
import com.sifang.modules.changes.vo.AddDesignChangeReq;
import com.sifang.modules.changes.vo.DesignChangeAuditReq;
import com.sifang.modules.customer.Service.CrmCustomerEntrySurveyRecordDetailService;
import com.sifang.modules.customer.Service.CustomerEntryComponentService;
import com.sifang.modules.customer.Service.CustomerEntryService;
import com.sifang.modules.customer.constant.CustomerEntryConstants;
import com.sifang.modules.customer.constant.PartnerConstants;
import com.sifang.modules.customer.constant.UserConstants;
import com.sifang.modules.customer.dao.CrmAcceptingReportDetailDao;
import com.sifang.modules.customer.dao.CrmCustomerEntryDesignDao;
import com.sifang.modules.customer.dao.CrmCustomerEntryProjectDao;
import com.sifang.modules.customer.dao.CrmCustomerEntrySurveyRecordDetailDao;
import com.sifang.modules.customer.entity.CrmAcceptingReportDetail;
import com.sifang.modules.customer.entity.CrmCustomerEntryDesign;
import com.sifang.modules.customer.entity.CrmCustomerEntrySurveyRecordDetail;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.platform.utils.AddressUtils;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmProjectSetting;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmTraderEmploye;
import com.sifang.modules.sunshine.SystemSetting.service.*;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sunshine.partnerManagement.dao.PartnerDao;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.FormSetUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.web.BaseController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Controller
@RequestMapping("${adminPath}/entryChanges/designInfo")
public class CrmCustomerEntryChangeDesignController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(CrmCustomerEntryChangeDesignController.class);
    @Autowired
    CustomerEntryChangeDesignService customerEntryChangeDesignService;
    @Autowired
    CustomerEntryChangeDesignComponentService designComponentService;
    @Autowired
    TraderEmployeService traderEmployeService;
    @Autowired
    CustomerEntryComponentService customerEntryComponentService;
    @Autowired
    PlanService planService;
    @Autowired
    CustomerEntryService customerService;
    @Autowired
    ProjectInfoSettingService projectService;
    @Autowired
    ProjectInstallService projectInstallService;
    @Autowired
    private FormSetService formSetService;
    @Autowired
    private PartnerDao partnerDao;
    @Autowired
    TraderService traderService;
    @Autowired
    private CrmCustomerEntryProjectDao crmCustomerEntryProjectDao;
    @Autowired
    private CrmCustomerEntryDesignDao crmCustomerEntryDesignDao;
    @Autowired
    private CrmCustomerEntrySurveyRecordDetailDao crmCustomerEntrySurveyRecordDetailDao;
    @Autowired
    private CrmCustomerEntryChangeDesignDetailDao changeDesignDetailDao;
    @ResponseBody
    @RequestMapping("addDesignChange")
    public Result addDesignChange(@Validated @RequestBody AddDesignChangeReq req) {
        try {
            return customerEntryChangeDesignService.addChangeDesign(req);
        } catch (BusinessException ex) {
            return Result.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error("add design change error", ex);
            return Result.fail("系统内部错误，设计变更申请失败！");
        }
    }
    @ResponseBody
    @RequestMapping("addDesignChangeHR")
    public Result addDesignChangeHR(@RequestBody List<AddDesignChangeReq>  req) {
        try {
            return customerEntryChangeDesignService.addChangeDesignHR(req);
        } catch (BusinessException ex) {
            return Result.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error("add design change error", ex);
            return Result.fail("系统内部错误，设计变更申请失败！");
        }
    }

    /**
     * 去选择电站页面
     */
    @RequestMapping("/toSelectEntry")
    public String toSelectEntry(HttpServletRequest request,Model model) {
        User user = UserUtils.getUser();
        //地址信息
        List<Record> pros = AddressUtils.findProvinceListByTraderId(CrmUtils.getCurrentTraderId(user.getId()), null);
        model.addAttribute("province", pros);
        model.addAttribute("partnerId", request.getParameter("partnerId"));
        return "modules/yangguang/changes/designInfoChange/selectEntry";
    }

    @ResponseBody
    @RequestMapping("cancelAddDesign/{id}")
    public Result cancelAddDesign(@PathVariable("id") String id) {
        try {
            return customerEntryChangeDesignService.cancelAddDesign(id);
        } catch (Exception ex) {
            logger.error("cancel design change error", ex);
            return Result.fail("系统内部错误，设计变更申请失败！");
        }
    }

    @ResponseBody
    @RequestMapping("tempDesignChange")
    public Result tempDesignChange(@RequestBody DesignChangeAuditReq req) {
        try {
            return customerEntryChangeDesignService.tempDesignChange(req);
        } catch (BusinessException ex) {
            logger.error("design change error", ex);
            return Result.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error("design change error", ex);
            return Result.fail("系统内部错误，审核失败！");
        }
    }

    @ResponseBody
    @RequestMapping("auditDesignChange")
    public Result auditDesignChange(@RequestBody DesignChangeAuditReq req) {
        try {
            return customerEntryChangeDesignService.auditDesignChange(req);
        } catch (BusinessException ex) {
            logger.error("design change error", ex);
            return Result.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error("design change error", ex);
            return Result.fail("系统内部错误，审核失败！");
        }
    }
    @ResponseBody
    @RequestMapping("auditDesignChangeHR")
    public Result auditDesignChangeHR(@RequestBody DesignChangeAuditReq req) {
        try {
            return customerEntryChangeDesignService.auditDesignChangeHR(req);
        } catch (BusinessException ex) {
            logger.error("design change error", ex);
            return Result.fail(ex.getMessage());
        } catch (Exception ex) {
            logger.error("design change error", ex);
            return Result.fail("系统内部错误，审核失败！");
        }
    }

    @RequestMapping("/toAddDesignChangePage")
    public String toAddDesignChangePage(HttpServletRequest request ,Model model) {
        String partnerId = request.getParameter("partnerId");
        model.addAttribute("partnerId",partnerId);
        if (PartnerConstants.PARTNER_ID_HR.equals(partnerId)) {
            return "modules/yangguang/changes/designInfoChange/addDesignChangeHR";
        }else {
            return "modules/yangguang/changes/designInfoChange/addDesignChange";
        }
    }


    public void common(Model model, String id) {
        CrmCustomerEntryChangeDesign design = customerEntryChangeDesignService.get(id);
        String entryId = design.getEntryId();
        CustomerEntry entry = customerService.getById(entryId);
        model.addAttribute("design", design);
        model.addAttribute("entry", entry);
        model.addAttribute("info2", formSetService.getListByCondition("08", entry.getPartnerId()));
        //多产品参数获取
        List<Record> entryProject = crmCustomerEntryProjectDao.getProjectsByEntryId(entry.getId());
        model.addAttribute("entryProject",entryProject);
        List<Record> changeDetails = changeDesignDetailDao.getDesignDetailsByNumber(design.getNumber());
        model.addAttribute("changeDetails", changeDetails);
        List<Record> componentList = designComponentService.findByDesignId(id);
        List<Record> preComponentList = componentList.stream().filter(e -> Objects.equals("0", e.getStr("flag"))).collect(Collectors.toList());
        List<Record> postComponentList = componentList.stream().filter(e -> Objects.equals("1", e.getStr("flag"))).collect(Collectors.toList());
        for (Record changeDetail : changeDetails) {
            String projectId = changeDetail.getStr("project_id");
            List<Record> preComList = preComponentList.stream().filter(r -> r.getStr("project_id").equals(projectId)).collect(Collectors.toList());
            List<Record> itemType = preComList.stream().filter(r -> r.getStr("item_type").equals("3")).collect(Collectors.toList());
            int preDesignCapacity = 0;
            for (Record record : itemType) {
                preDesignCapacity = preDesignCapacity + Integer.parseInt(record.getStr("model")) * record.getInt("num");
            }
            changeDetail.set("preDesignCapacity", preDesignCapacity);
            changeDetail.set("preComponentList", preComList);
            List<Record> postComList = postComponentList.stream().filter(r -> r.getStr("project_id").equals(projectId)).collect(Collectors.toList());
            changeDetail.set("postComponentList", postComList);
            List<Record> itemType1 = postComList.stream().filter(r -> r.getStr("item_type").equals("3")).collect(Collectors.toList());
            int postDesignCapacity = 0;
            for (Record record : itemType1) {
                postDesignCapacity = postDesignCapacity + Integer.parseInt(record.getStr("model")) * record.getInt("num");
            }
            changeDetail.set("postDesignCapacity", postDesignCapacity);
        }
    }
    /**
     * 审核页面
     */
    @RequestMapping("/toAuditPage/{id}/{partnerId}")
    public String toAuditPage(@PathVariable("id") String id,@PathVariable("partnerId") String partnerId , Model model) {
        model.addAttribute("id", id);
        model.addAttribute("fromAudit", "1");
        if (PartnerConstants.PARTNER_ID_HR.equals(partnerId)){
            common(model, id);
            return "modules/yangguang/changes/designInfoChange/designChangeDetailHR";
        }
        return "modules/yangguang/changes/designInfoChange/designChangeDetail";
    }

    @RequestMapping("/toChangeDetail/{id}/{partnerId}")
    public String toChangeDetail(@PathVariable("id") String id,@PathVariable("partnerId") String partnerId , Model model) {
        model.addAttribute("id", id);
        model.addAttribute("fromAudit", "2");
        if (PartnerConstants.PARTNER_ID_HR.equals(partnerId)){
            common(model, id);
            return "modules/yangguang/changes/designInfoChange/designChangeDetailHR";
        }else {
            return "modules/yangguang/changes/designInfoChange/designChangeDetail";
        }

    }

    /**
     * 待审核列表
     */
    @RequestMapping("waitAuditList")
    public String waitAuditList(Model model) {
        User user = UserUtils.getUser();
        model.addAttribute("user", user);
        return "modules/yangguang/changes/designInfoChange/waitAuditList";
    }

    /**
     * 变更记录
     */
    @RequestMapping("changeList")
    public String changeList(Model model) {
        User user = UserUtils.getUser();
        model.addAttribute("user", user);
        String partnerIds="";
        if(User.USER_TYPE_KJ.equals(user.getUserType()) || User.USER_TYPE_ADVISOR.equals(user.getUserType())){
            //获取关联资方
            partnerIds=traderService.getPartnerIdByTraderId(user.getTraderId());
        }
        model.addAttribute("partnerList",partnerDao.partnerList(partnerIds));
        return "modules/yangguang/changes/designInfoChange/changeList";
    }

    /**
     * 待审核列表数据
     */
    @ResponseBody
    @RequestMapping(value = "listData")
    public Object listData(HttpServletRequest request) {
        LayuiPage<Record> page = new LayuiPage<>(request);
        Map<String, String> params = getParams(request);
        params.put("status", "0");
        User user = UserUtils.getUser();
        extractTraderEmployee(user, params);
        Operator operator = Operator.of(user.getId(), CrmUtils.getUserXM(user), user.getUserType());
        customerEntryChangeDesignService.listData(page, params, operator);
        return page.renderJson();
    }


    /**
     * 变更记录列表
     */
    @ResponseBody
    @RequestMapping(value = "changeListData")
    public Object changeListData(HttpServletRequest request) {
        LayuiPage<Record> page = new LayuiPage<>(request);
        Map<String, String> params = getParams(request);
        params.put("status", "1,2,3");
        User user = UserUtils.getUser();
        extractTraderEmployee(user, params);
        customerEntryChangeDesignService.listData(page, params, Operator.of(user.getId(), CrmUtils.getUserXM(user), user.getUserType()));
        return page.renderJson();
    }

    private void extractTraderEmployee(User user, Map<String, String> params) {
        CrmTraderEmploye employee = traderEmployeService.findByUserId(user.getId());
        if (employee != null) {
            params.put("engineerId", employee.getId());
        }
    }

    @ResponseBody
    @RequestMapping("selectNumber/{stationCode}")
    public Result selectNumber(@PathVariable("stationCode") String stationCode) {
        Result ret = Result.ok();
        Map<String, Object> resMap = Maps.newHashMap();
        CustomerEntry customerEntry = customerService.findCustomerEntryById(stationCode);
        if (customerEntry == null) {
            ret = Result.fail("未找到电站信息！");
            return ret;
        }
//        if (!CustomerEntryChangeDesignService.validStatus(customerEntry.getStatus())) {
//            return Result.fail(CustomerEntryChangeDesignService.invalidStatusMsg());
//        }

        //判断电站与角色是否相符
        User user = UserUtils.getUser();
        Operator operator = Operator.of(user.getId(), CrmUtils.getUserXM(user), user.getUserType());
        if (StringUtil.equalsAny(operator.getUserType(), UserConstants.TYPE_TRADER, User.USER_TYPE_ADVISOR)) {
            Record record = CrmUtils.getUserTrader(operator.getUserType(), operator.getUserId());
            String traderId = record.getStr("id");
            if (UserConstants.TYPE_TRADER.equals(operator.getUserType())) {  //代理商
                if ("1".equals(record.getStr("type"))) {  // 1.一级代理商 2.二级代理商
                    if (!customerEntry.getDistributorId().equals(traderId)) {
                        ret = Result.fail("未找到电站信息！");
                        return ret;
                    }
                } else {  //二级代理商
                    if (UserConstants.TYPE_TRADER.equals(operator.getUserType())) {
                        //代理商只能查看自己的
                        if (!traderId.equals(customerEntry.getCreateTraderId())) {
                            ret = Result.fail("未找到电站信息！");
                            return ret;
                        }
                    }
                }
            } else { //代理商人员
                if (!traderId.equals(customerEntry.getCreateTraderId())) {
                    ret = Result.fail("未找到电站信息！");
                    return ret;
                }
            }
        }

        resMap.put("customerEntry", customerEntry);
        if (PartnerConstants.PARTNER_ID_HR.equals(customerEntry.getPartnerId())){
            List<Record> projectList = projectService.getEntryProjectByEntryId(customerEntry.getId());
            resMap.put("projectList",projectList);
        }else {
            resMap.put("project", projectService.getById(customerEntry.getProjectId()));
        }
        resMap.put("insta", projectInstallService.findProjectInstalls());

        List<Record> componentList = customerEntryComponentService.findByEntryId(customerEntry.getId());
        List<Record> assemblyList = componentList.stream().filter(r -> r.getStr("item_type").equals("3")).collect(Collectors.toList());
        List<Record> inverterList = componentList.stream().filter(r -> r.getStr("item_type").equals("1")).collect(Collectors.toList());
        List<Record> gridConnectionList = componentList.stream().filter(r -> r.getStr("item_type").equals("2")).collect(Collectors.toList());
        List<Record> gridSupportList = componentList.stream().filter(r -> r.getStr("item_type").equals("4")).collect(Collectors.toList());
        setVal(assemblyList, "组件");
        setVal(inverterList, "逆变器");
        setVal(gridConnectionList, "并网箱");
        setVal(gridSupportList, "支架");
        resMap.put("assemblyList", assemblyList);
        resMap.put("inverterList", inverterList);
        resMap.put("gridConnectionList", gridConnectionList);
        resMap.put("gridSupportList", gridSupportList);

        String projectId = customerEntry.getProjectId();
        if(PartnerConstants.PARTNER_ID_HR.equals(customerEntry.getPartnerId())){
            List<Record> projects = crmCustomerEntryProjectDao.getProjectsByEntryId(customerEntry.getId());
            projectId = projects.get(0).getStr("id");
        }
        CrmProjectSetting pro = projectService.getById(projectId);

        // 获取系统设置的电器材料
        List<Record> allElectric = planService.findAllElectric();
        List<Record> records = planService.getElectricSet("3");
        List<Record> sysAssemblyList = new ArrayList<>();
        if(!PartnerConstants.PARTNER_ID_HR.equals(customerEntry.getPartnerId())){
            for (Record record : records) {
                if (Integer.valueOf(record.get("model")) >= pro.getAssemblySpecs()){
                    sysAssemblyList.add(record);
                }
            }
            resMap.put("sysAssemblyList", sysAssemblyList);
        }
        List<Record> sysInverterList = allElectric.stream().filter(r -> r.getStr("type").equals("1")).collect(Collectors.toList());
        List<Record> sysGridConnectionList = allElectric.stream().filter(r -> r.getStr("type").equals("2")).collect(Collectors.toList());
        List<Record> sysGridSupportList = allElectric.stream().filter(r -> r.getStr("type").equals("4")).collect(Collectors.toList());
        resMap.put("sysInverterList", sysInverterList);
        resMap.put("sysGridConnectionList", sysGridConnectionList);
        resMap.put("sysGridSupportList", sysGridSupportList);
        resMap.put("formSet", FormSetUtils.getFormPartSetByStep(null, "2", "08", customerEntry.getPartnerId(), false));
        resMap.put("info2", formSetService.getListByCondition("08", pro.getManagement()));
        if(PartnerConstants.PARTNER_ID_HR.equals(customerEntry.getPartnerId())){
            List<Record> entryProject = crmCustomerEntryProjectDao.getProjectsByEntryId(customerEntry.getId());
            List<CrmCustomerEntryDesign> entryDesigns = crmCustomerEntryDesignDao.findByEntryId(customerEntry.getId());
            List<CrmCustomerEntrySurveyRecordDetail> entrySurveys = crmCustomerEntrySurveyRecordDetailDao.findByEntryId(customerEntry.getId());
            if (CustomerEntryConstants.SCHEME_TYPE_TWO.equals(customerEntry.getSchemeType())) {
                resMap.put("compose", customerService.findPlanInfoEntryId(customerEntry.getId()));
            } else {//标准方案
                List<Record> composeOnes = new ArrayList<>();
                for(CrmCustomerEntryDesign entryDesign:entryDesigns){
                    Record composeOne = customerService.findByEntrySchemeId(entryDesign.getSchemeId());
                    if(composeOne!=null){
                        composeOne.set("projectId",entryDesign.getProjectId());
                    }
                    composeOnes.add(composeOne);
                }
                resMap.put("composeOneHr", composeOnes);
            }
            for(Record project:entryProject){
                if(project!=null&&StringUtil.isNotBlank(project.getStr("id"))){
                    for (Record record : records) {
                        if (Integer.valueOf(record.get("model")) >= project.getInt("assembly_specs")){
                            Record record1 = new Record().setColumns(record);
                            record1.set("projectId",project.getStr("id"));
                            sysAssemblyList.add(record1);
                        }
                    }
                }
            }
            resMap.put("sysAssemblyList", sysAssemblyList);
            resMap.put("entryDesigns",entryDesigns);
        }
        ret.setData(resMap);
        return ret;
    }

    @ResponseBody
    @RequestMapping("designChangeDetail/{id}")
    public Result designChangeDetail(@PathVariable("id") String id) {
        Result ret = Result.ok();
        CrmCustomerEntryChangeDesign design = customerEntryChangeDesignService.get(id);
        String entryId = design.getEntryId();
        CustomerEntry customerEntry = customerService.getById(entryId);
        Map<String, Object> resMap = Maps.newHashMap();

        resMap.put("design", design);
        resMap.put("customerEntry", customerEntry);
        resMap.put("project", projectService.getById(customerEntry.getProjectId()));
        resMap.put("insta", projectInstallService.findProjectInstalls());

        List<Record> componentList = designComponentService.findByDesignId(id);
        List<Record> preComponentList = componentList.stream().filter(e -> Objects.equals("0", e.getStr("flag"))).collect(Collectors.toList());
        List<Record> postComponentList = componentList.stream().filter(e -> Objects.equals("1", e.getStr("flag"))).collect(Collectors.toList());

        List<Record> assemblyList = preComponentList.stream().filter(r -> r.getStr("item_type").equals("3")).collect(Collectors.toList());
        List<Record> inverterList = preComponentList.stream().filter(r -> r.getStr("item_type").equals("1")).collect(Collectors.toList());
        List<Record> gridConnectionList = preComponentList.stream().filter(r -> r.getStr("item_type").equals("2")).collect(Collectors.toList());
        List<Record> gridSupportList = preComponentList.stream().filter(r -> r.getStr("item_type").equals("4")).collect(Collectors.toList());
        setVal(assemblyList, "组件");
        setVal(inverterList, "逆变器");
        setVal(gridConnectionList, "并网箱");
        setVal(gridSupportList, "支架");

        List<Record> postAssemblyList = postComponentList.stream().filter(r -> r.getStr("item_type").equals("3")).collect(Collectors.toList());
        List<Record> postInverterList = postComponentList.stream().filter(r -> r.getStr("item_type").equals("1")).collect(Collectors.toList());
        List<Record> postGridConnectionList = postComponentList.stream().filter(r -> r.getStr("item_type").equals("2")).collect(Collectors.toList());
        List<Record> postGridSupportList = postComponentList.stream().filter(r -> r.getStr("item_type").equals("4")).collect(Collectors.toList());
        setVal(postAssemblyList, "组件");
        setVal(postInverterList, "逆变器");
        setVal(postGridConnectionList, "并网箱");
        setVal(postGridSupportList, "支架");

        resMap.put("assemblyList", assemblyList);
        resMap.put("inverterList", inverterList);
        resMap.put("gridConnectionList", gridConnectionList);
        resMap.put("gridSupportList", gridSupportList);
        resMap.put("postAssemblyList", postAssemblyList);
        resMap.put("postInverterList", postInverterList);
        resMap.put("postGridConnectionList", postGridConnectionList);
        resMap.put("postGridSupportList", postGridSupportList);

        resMap.put("preCapacity", calcCapacity(assemblyList));
        resMap.put("postCapacity", calcCapacity(postAssemblyList));
        resMap.put("formSet", FormSetUtils.getFormPartSetByStep(null, "2", "08", customerEntry.getPartnerId(), false));
        resMap.put("info2", formSetService.getListByCondition("08", customerEntry.getPartnerId()));
        ret.setData(resMap);
        return ret;
    }

    private String calcCapacity(List<Record> assemblyList) {
        try {
            long total = 0L;
            for (Record r : assemblyList) {
                String model = r.getStr("model");
                Integer num = r.getInt("num");
                total += Long.parseLong(model) * num;
            }
            return Long.toString(total);
        } catch (Exception ex) {
            logger.error("calc capacity error", ex);
            return "-";
        }
    }

    private void setVal(List<Record> list, String name) {
        for (Record record : list) {
            record.set("label", name);
        }
    }

}
