package com.dk.mdm.service.mst;

import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.model.pojo.mst.StaffRight;
import com.dk.common.model.response.mst.OrgResponse;
import com.dk.common.model.response.mst.StaffResponse;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.common.util.ExcelUtils;
import com.dk.mdm.infrastructure.convert.mst.CustomerConvert;
import com.dk.mdm.infrastructure.util.AuthUtils;
import com.dk.mdm.mapper.common.CommonMapper;
import com.dk.mdm.mapper.core.OrganizationMapper;
import com.dk.mdm.mapper.mst.OrgMapper;
import com.dk.mdm.mapper.mst.StaffMapper;
import com.dk.mdm.model.pojo.mst.Customer;
import com.dk.mdm.mapper.mst.CustomerMapper;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.pojo.mst.DictionaryData;
import com.dk.mdm.model.pojo.mst.GoodsSku;
import com.dk.mdm.model.query.mst.CustomerQuery;
import com.dk.mdm.model.query.mst.OrgQuery;
import com.dk.mdm.model.query.mst.StaffQuery;
import com.dk.mdm.model.response.mst.CustomerResponse;
import com.dk.mdm.model.vo.mac.*;
import com.dk.mdm.model.vo.mst.CustomerVO;
import com.dk.mdm.model.vo.mst.DictionaryDataVO;
import com.dk.mdm.service.common.CommonService;
import com.dk.mdm.service.mac.OtherPayableService;
import com.dk.mdm.service.mac.OtherReceivableService;
import com.dk.mdm.service.mac.ReceiptService;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Transactional
public class CustomerService extends BaseService<Customer> {

    @Override
    public BaseMapper<Customer> getRepository() {
        return customerMapper;
    }

    @Autowired
    private CustomerMapper customerMapper;


    @Autowired
    private CustomerConvert customerConvert;

    @Autowired
    private CommonService commonService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private OtherReceivableService otherReceivableService;

    @Autowired
    private ReceiptService receiptService;


    @Autowired
    private AuthUtils authUtils;

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private DictionaryDataService dictionaryDataService;

    /**
     * @desc : 重写主键
     * @author : 于继渤
     * @date : 2024/2/29 20:29
     */
    @Override
    public String getPrimaryKey() {
        return "cus_id";
    }


    /**
     * @desc : 查询
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    @Pagination
    public ResponseResultVO<PageList<CustomerResponse>> selectByCond(CustomerQuery customerQuery) {
        return super.mergeListWithCount(customerQuery, customerMapper.selectByCond(customerQuery),
                customerMapper.countByCond(customerQuery));
    }

    /**
     * @desc : 新建
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insert(CustomerVO customerVO) {
        Customer customer = customerConvert.convertToPo(customerVO);
        //设置编码
        Map<String, Object> uniqueNoteCode = commonService.getUniqueNoteCode(Constant.docNameConstant.CUSTOMER.getName(), true);
        customer.setCusId(uniqueNoteCode.get("outId").toString());
        customer.setCusCode(uniqueNoteCode.get("outNote").toString());

        // 同商户 电话不同
        Long count = customerMapper.countByCond(
                new CustomerQuery().setCpId(customer.getCpId()).setCusPhone(customer.getCusPhone()).setFlgValid(true)
        );
        if (count > 0) {
            return ResponseResultUtil.error(ErrorCodeEnum.CUSTOMER_SAME_COMPANY_TELEPHONE.getCode(),
                    ErrorCodeEnum.CUSTOMER_SAME_COMPANY_TELEPHONE.getMessage());
        }
        List<String> followStaff = new ArrayList<>();
        String staffId = authUtils.getStaff().getStaffId();
        followStaff.add(staffId);
        customer.setFollowStaffs(followStaff);
        if (customer.getSaleStatus() == null) {
            //新建默认就是潜客
            customer.setSaleStatus(Constant.saleCustomerStatusConstant.SALE_STATUS_POTE.getName());
        }

        //报备人
        customer.setReportStaff(staffId);
        //报备日期
        customer.setReportTime(LocalDateTime.now());
        // 如果有初始欠款，那么就是成交状态
        if(customerVO != null && customerVO.getStartAmount() != null && customerVO.getStartAmount().compareTo(BigDecimal.ZERO) != 0){
            customer.setSaleStatus(Constant.SaleStatus.CHENGJIAO.getName());
        }
        ResponseResultVO<?> insert = super.insert(customer);
        //说明有起始欠款  需要插入其他支出
        if (customerVO != null && customerVO.getInitialPaymentId() != null
                && customerVO.getInitialPaymentId().equals(Constant.initialPaymentType.DEBT.getName())) {
            //先组装明细
            List<OtherReceivableItemVO> itemList = new ArrayList<>();
            OtherReceivableItemVO otherReceivableItemVO = new OtherReceivableItemVO();
            Map<String, Object> param = new HashMap<>();
            param.put("cpId", authUtils.getStaff().getCpId());
            param.put("dictCode", "基础资料-收入");
            param.put("dataValue", "期初");
            Map<String, Object> data = commonMapper.selectDictionaryData(param);
            if (data != null && data.size() > 0) {
                String dataId = String.valueOf(data.get("dataId"));
                otherReceivableItemVO.setReceivableType(dataId);
                otherReceivableItemVO.setAmtReceivable(customerVO.getStartAmount());
                itemList.add(otherReceivableItemVO);
                //调用 新建其他支出
                OtherReceivableVO otherReceivableVO = new OtherReceivableVO().setBusinessType(0).setObjectId(customer.getCusId())
                        .setSumAmtReceivable(customerVO.getStartAmount()).setStaffId(customer.getStaffId())
                        .setOrgId(customer.getOrgId()).setAccDate(LocalDate.now()).setMakeStaff(customer.getReportStaff())
                        .setItemList(itemList).setSumAmtRec(BigDecimal.ZERO);
                otherReceivableService.insert(otherReceivableVO);
            }else{
                // 插入期初
                DictionaryDataVO dictionaryDataVO = new DictionaryDataVO();
                dictionaryDataVO.setDictCode("基础资料-收入");
                dictionaryDataVO.setCpId(authUtils.getStaff().getCpId());
                dictionaryDataVO.setDataValue("期初");
                ResponseResultVO<?> insertDic = dictionaryDataService.insert(dictionaryDataVO);
                if (insertDic.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
                    DictionaryData dataDic = (DictionaryData)insertDic.getData();
                    String dataId = dataDic.getDataId();
                    otherReceivableItemVO.setReceivableType(dataId);
                    otherReceivableItemVO.setAmtReceivable(customerVO.getStartAmount());
                    itemList.add(otherReceivableItemVO);
                    //调用 新建其他支出
                    OtherReceivableVO otherReceivableVO = new OtherReceivableVO().setBusinessType(0).setObjectId(customer.getCusId())
                            .setSumAmtReceivable(customerVO.getStartAmount()).setStaffId(customer.getStaffId())
                            .setOrgId(customer.getOrgId()).setAccDate(LocalDate.now()).setMakeStaff(customer.getReportStaff())
                            .setItemList(itemList).setSumAmtRec(BigDecimal.ZERO);
                    otherReceivableService.insert(otherReceivableVO);
                } else {
                    return ResponseResultUtil.error(1111,"基础资料-收入的期初插入失败");
                }

            }
        }
        //初始款项-预收 240530
        else if (customerVO != null && customerVO.getInitialPaymentId() != null
                && customerVO.getInitialPaymentId().equals(Constant.initialPaymentType.PAYMENT.getName())) {
            //先组装明细
            List<RecPayItemVO> itemList = new ArrayList<>();
            RecPayItemVO recPayItemVO = new RecPayItemVO();
            recPayItemVO.setAccDate(LocalDate.now());
            recPayItemVO.setCpId(customer.getCpId());
            recPayItemVO.setMacId(customerVO.getMacId());
            recPayItemVO.setAmtRec(customerVO.getStartAmount());
            recPayItemVO.setMakeStaff(customer.getReportStaff());
            itemList.add(recPayItemVO);
            RecPayVO recPayVO = new RecPayVO().setObjectId(customer.getCusId()).setAccDate(LocalDate.now())
                            .setSumAmtRec(customerVO.getStartAmount()).setStaffId(customer.getStaffId())
                            .setOrgId(customer.getOrgId()).setMakeStaff(customer.getReportStaff())
                    .setCpId(customer.getCpId()).setRpType(Constant.RpType.SHOU_KUAN.getName())
                    .setItemList(itemList);

            receiptService.insertReceipt(recPayVO);
        }

        if (insert.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
            return ResponseResultUtil.success(customer);
        } else {
            return insert;
        }

    }

    /**
     * @desc : 编辑
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> update(CustomerVO customerVO) {
        Customer customer = customerConvert.convertToPo(customerVO);
        super.updateByUuid(customer);
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 跟据id查询
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    public ResponseResultVO selectCustomerById(String id) {
        CustomerResponse customerResponse = customerMapper.selectCustomerById(id);
        if (customerResponse == null) {
            return ResponseResultUtil.error(ResponseCodeEnum.SELECT_NULL);
        }
        return ResponseResultUtil.success(customerResponse);
    }

    /**
     * @desc : 跟据id查询
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    public ResponseResultVO<CustomerResponse> selectByIdRespone(String id) {
        CustomerResponse customerResponse = customerMapper.selectByIdRespone(id);
        if (customerResponse == null) {
            return ResponseResultUtil.error(ResponseCodeEnum.SELECT_NULL);
        }
        return ResponseResultUtil.success(customerResponse);
    }

    /**
     * @desc : 不分页查询
     * @author : 于继渤
     * @date : 2023/1/5 9:39
     */
    public ResponseResultVO<List<CustomerResponse>> selectByCondNoPage(CustomerQuery customerQuery) {
        List<CustomerResponse> customerResponses = customerMapper.selectByCond(customerQuery);
        return ResponseResultUtil.success(customerResponses);
    }

    /**
     * @desc   : 导入
     * @author : 常皓宁
     * @date   : 2024/6/13 14:21
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<String> importCUS(List<Customer> list, HttpServletResponse response, @PathVariable Integer cpId) {
        List<Customer> messageList = new ArrayList<>();
        Workbook workbook = null;
        Boolean importMessage = false;
        //规则校验
        for (Customer customer : list) {
            customer.setCpId(cpId);
            customer.setErrorMessage("");
            //TODO 校验规则
            //客户编号不能为空
            if(customer.getCusCode() == null){
                customer.setErrorMessage(customer.getErrorMessage() + "客户编号不能为空,");
                importMessage = true;
            }
            //客户编号不能重复
            if(customer.getCusCode() != null){
                // 同商户 客编不同
                Long count = customerMapper.countByCond(
                        new CustomerQuery().setCpId(customer.getCpId()).setCusCode(customer.getCusCode()).setFlgValid(true)
                );
                if (count > 0) {
                    customer.setErrorMessage(customer.getErrorMessage() + "客户编码已存在,");
                    importMessage = true;
                }
            }
            //客户名称不能为空
            if(customer.getCusName() == null){
                customer.setErrorMessage(customer.getErrorMessage() + "客户名称不能为空,");
                importMessage = true;
            }
            //电话不能相同
            if(customer.getCusPhone() != null){
                // 同商户 电话不同
                Long count = customerMapper.countByCond(
                        new CustomerQuery().setCpId(customer.getCpId()).setCusPhone(customer.getCusPhone()).setFlgValid(true)
                );
                if (count > 0) {
                    customer.setErrorMessage(customer.getErrorMessage() + "当前电话号码已存在,");
                    importMessage = true;
                }
                //客户电话规则校验
                if(!customer.getCusPhone().matches("^1[34578]\\d{9}$")){
                    customer.setErrorMessage(customer.getErrorMessage() + "客户电话规则不正确,");
                    importMessage = true;
                }
            }
            //客户电话不能为空
            else{
                customer.setErrorMessage(customer.getErrorMessage() + "客户电话不能为空,");
                importMessage = true;
            }
            //联系电话规则校验
            if(!customer.getContactPhone().matches("^1[34578]\\d{9}$")){
                customer.setErrorMessage(customer.getErrorMessage() + "联系电话规则不正确,");
                importMessage = true;
            }
            //部门
            if(customer.getOrgName() != null){
                String orgName = customer.getOrgName();
                OrgResponse orgResponse = orgMapper.selectByUuId(new OrgQuery().setOrgName(orgName).setCpId(cpId));
                if(orgResponse == null){
                    customer.setErrorMessage(customer.getErrorMessage() + "部门填写错误,");
                    importMessage = true;
                }else{
                    customer.setOrgId(orgResponse.getOrgId());
                }
            }else{
                customer.setErrorMessage(customer.getErrorMessage() + "部门不能为空");
                importMessage = true;
            }
            //业务员
            if(customer.getStaffCode() != null){
                String staffCode = customer.getStaffCode();
                StaffResponse staffResponse = staffMapper.selectByUuId(new StaffQuery().setStaffCode(staffCode).setCpId(cpId));
                if(staffResponse == null){
                    customer.setErrorMessage(customer.getErrorMessage() + "业务员编码填写错误,");
                    importMessage = true;
                }else{
                    customer.setStaffId(staffResponse.getStaffId());
                }
            }else{
                customer.setErrorMessage(customer.getErrorMessage() + "业务员编码不能为空,");
                importMessage = true;
            }
            //报备人
            if(customer.getReportStaffCode() != null){
                String reportStaffCode = customer.getReportStaffCode();
                StaffResponse staffResponse = staffMapper.selectByUuId(new StaffQuery().setStaffCode(reportStaffCode).setCpId(cpId));
                if(staffResponse == null){
                    customer.setErrorMessage(customer.getErrorMessage() + "报备人编码填写错误,");
                    importMessage = true;
                }else{
                    customer.setReportStaff(staffResponse.getStaffId());
                }
            }else{
                customer.setErrorMessage(customer.getErrorMessage() + "报备人编码不能为空,");
                importMessage = true;
            }
            messageList.add(customer);
        }
        //导出错误提示
        if (importMessage){
            workbook = ExcelUtils.exportExcelUrl(messageList,"错误数据反馈","错误数据反馈",Customer.class,"客户档案错误数据反馈.xls", response);
            UUID uuid = UUID.randomUUID();
            String randomUUIDString = uuid.toString();
            //TODO 导出文件位置
            String fileName = "D:/练习/" + randomUUIDString;
            File outputFile = new File(fileName);
            //创建文件夹
            if(!outputFile.exists()){
                outputFile.mkdir();
            }
            File uploadFile = new File(fileName,"客户档案错误数据反馈.xls");
            try (FileOutputStream fos = new FileOutputStream(uploadFile)) {
                workbook.write(fos);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return ResponseResultUtil.error(-300,"D:/练习/" + randomUUIDString + "/客户档案错误数据反馈.xls");
        }
        else{
            //插入数据
            for(Customer customer:messageList){
                //新建默认就是潜客
                customer.setSaleStatus(Constant.saleCustomerStatusConstant.SALE_STATUS_POTE.getName());
                //报备日期
                customer.setReportTime(LocalDateTime.now());
                super.insert(customer);
            }
            return ResponseResultUtil.success();
        }
    }
}
