package com.huyi.service.supplierCreditLine.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.huyi.service.base.entity.*;
import com.huyi.service.base.service.*;
import com.huyi.service.creditLine.service.CreditLineService;
import com.huyi.service.supplierCreditLine.service.SupplierCreditLineService;
import com.keao.tianhu.core.exception.base.BusinessException;
import com.keao.tianhu.starter.mybatis.plus.entity.QueryRequest;
import com.tianhu.common.core.constant.SalaryConstants;
import com.tianhu.common.core.domain.R;
import com.tianhu.common.core.utils.*;
import com.tianhu.common.core.utils.file.ExcelFileUtils;
import com.tianhu.common.core.web.controller.BaseController;
import com.tianhu.common.core.web.domain.AjaxResult;
import com.tianhu.common.log.annotation.Log;
import com.tianhu.common.log.enums.BusinessType;
import com.tianhu.common.security.annotation.PreAuthorize;
import com.tianhu.common.security.service.TokenService;
import com.tianhu.system.api.domain.SysUser;
import com.tianhu.system.api.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;


/**
 * 供应商授信额度Controller
 *
 * @author pxh
 * @date 2021-02-04
 */

@RestController
@RequestMapping("/supplierCreditLine")
public class SupplierCreditLineController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(SupplierCreditLineController.class);
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SupplierCreditLineService supplierCreditLineService;
    @Autowired
    private IZcFinanceInfService zcFinanceInfService;
    @Autowired
    private IZcFinanceProComRelService iZcFinanceProComRelService;
    @Autowired
    private IZcFinanceQuotaConRelService iZcFinanceQuotaConRelService;
    @Autowired
    private IZcFinanceContractService iZcFinanceContractService;
    @Autowired
    private IZcFinanceSupplierQuotaService iZcFinanceSupplierQuotaService;
    @Autowired
    private ISysCompanyService iSysCompanyService;
    @Autowired
    private ISysCompanyRelService iSysCompanyRelService;

    /**
     * 供应商授信额度列表
     * @param scyName 企业名称
     * @param AmountA 授信额度范围
     * @param AmountB 授信额度范围
     * @param zfpcrStatus 状态
     * @param request
     * @return
     */
    @PreAuthorize(hasPermi = "supplierCredit:line:list")
    @GetMapping("/list")
    public R list(//企业名称
                  @RequestParam(required=false) String scyName,
                  //授信额度范围
                  @RequestParam (required=false) String AmountA,
                  //授信额度范围
                  @RequestParam (required=false) String AmountB,
                  //状态(00:有效 01:失效)
                  @RequestParam (required=false) String zfpcrStatus,
                  //核心企业授信额度ID
                  @RequestParam (required=false) String zfsqId,
                  QueryRequest request) {
        //查询当前操作员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser use = userInfo.getSysUser();
        //获取企业
        String companyId = use.getCompanyId();
        Map map = new HashMap();
        if (!SalaryConstants.OPEX.equals(companyId)) {
            map.put("companyId", companyId);
        }
        //企业名称
        map.put("scyName",scyName);
        //授信额度范围
        map.put("AmountA",CommonUtil.objToBigDecimal(AmountA));
        map.put("AmountB",CommonUtil.objToBigDecimal(AmountB));
        //状态(00:有效 01:失效)
        map.put("zfpcrStatus",zfpcrStatus);
        //核心企业授信额度ID
        map.put("zfsqId",zfsqId);
        IPage<Map> list = supplierCreditLineService.selectSupplierCreditLineList(map, request);
        return R.ok(list);
    }

    /**
     * 付款信息详情
     */
    @PreAuthorize(hasPermi = "supplierCredit:line:query")
    @GetMapping(value = "/{zfsqId}")
    public AjaxResult getInfo(@PathVariable("zfsqId") String zfsqId)
    {
       Map map = new HashMap();
       map.put("zfsqId",zfsqId);
       List<Map> list = supplierCreditLineService.selectSupplierCreditLineDetail(map);
        return AjaxResult.success(list);
    }

    /**
     * 新增供应商授信额度
     * @param zcFinanceSupplierQuota
     * @return
     * @throws Exception
     */
    @PreAuthorize(hasPermi = "supplierCredit:line::add")
    @Log(title = "供应商授信管理", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    @PostMapping
    public AjaxResult add(@RequestBody ZcFinanceSupplierQuota zcFinanceSupplierQuota)throws Exception
    {
        //获取此操作员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser user = userInfo.getSysUser();
        String userId = user.getUserId() + "";
        //供应商
        String zfsqCompanyId = zcFinanceSupplierQuota.getZfsqCompanyId();
        //授信额度
        String zfsqAmount = zcFinanceSupplierQuota.getZfsqAmount();
        //核心企业授信额度ID
        String zfsqCoreQuotaId = zcFinanceSupplierQuota.getZfsqCoreQuotaId();
        if (CommonUtil.isEmpty(zfsqCompanyId)){
            throw new Exception("企业名称不能为空");
        }
        if (CommonUtil.isEmpty(zfsqAmount)){
            throw new Exception("授信额度不能为空");
        }
        //查询核心企业授信额度ID下的供应商授信额度总和
        QueryWrapper<ZcFinanceSupplierQuota> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("zfsq_core_quota_id",zfsqCoreQuotaId);
        queryWrapper.select("IFNULL(CAST(ROUND(SUM(zfsq_amount),2)AS CHAR),'0.00') AS zfsqAmount");
        ZcFinanceSupplierQuota supplierQuota = iZcFinanceSupplierQuotaService.getOne(queryWrapper);
        String totalAmount = supplierQuota.getZfsqAmount();
        //额度总和 + 本次授信额度
        totalAmount = AmtUtil.add(totalAmount,zfsqAmount,2);
        //查询核心企业的授信额度
        ZcFinanceProComRel zcFinanceProComRel = iZcFinanceProComRelService.getById(zfsqCoreQuotaId);
        String zfpcrAmount = zcFinanceProComRel.getZfpcrAmount();
        //此核心企业下的供应商授信额度 > 核心企业的授信额度 => 授信额度已超额
        int result = StringUtils.compare(totalAmount,zfpcrAmount);
        if (result == 1){
            throw new Exception("授信额度已超额");
        }
        //主键
        String zfsqId = IdUtils.fastSimpleUUID();
        zcFinanceSupplierQuota.setZfsqId(zfsqId);
        //状态(00:有效 01:失效)
        zcFinanceSupplierQuota.setZfsqStatus("00");
        //创建人
        zcFinanceSupplierQuota.setCreateBy(userId);
        //创建时间
        zcFinanceSupplierQuota.setCreateTime(DateUtils.getNowDate());
        iZcFinanceSupplierQuotaService.createZcFinanceSupplierQuota(zcFinanceSupplierQuota);
        return AjaxResult.success();
    }

    /**
     * 修改供应商授信额度
     * @param zcFinanceSupplierQuota
     * @return
     * @throws Exception
     */
    @PreAuthorize(hasPermi = "supplierCredit:line:edit")
    @Log(title = "供应商授信管理", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    @PutMapping
    public AjaxResult update(@RequestBody ZcFinanceSupplierQuota zcFinanceSupplierQuota)throws Exception
    {
        //获取此操作员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser user = userInfo.getSysUser();
        String userId = user.getUserId() + "";
        //供应商
        String zfsqCompanyId = zcFinanceSupplierQuota.getZfsqCompanyId();
        //授信额度
        String zfsqAmount = zcFinanceSupplierQuota.getZfsqAmount();
        //核心企业授信额度ID
        String zfsqCoreQuotaId = zcFinanceSupplierQuota.getZfsqCoreQuotaId();
        if (CommonUtil.isEmpty(zfsqCompanyId)){
            throw new Exception("企业名称不能为空");
        }
        if (CommonUtil.isEmpty(zfsqAmount)){
            throw new Exception("授信额度不能为空");
        }
        //查询核心企业授信额度ID下的供应商授信额度总和
        QueryWrapper<ZcFinanceSupplierQuota> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("zfsq_core_quota_id",zfsqCoreQuotaId);
        queryWrapper.eq("zfsq_status","00");
        queryWrapper.select("IFNULL(CAST(ROUND(SUM(zfsq_amount),2)AS CHAR),'0.00') AS zfsqAmount");
        ZcFinanceSupplierQuota supplierQuota = iZcFinanceSupplierQuotaService.getOne(queryWrapper);
        String totalAmount = supplierQuota.getZfsqAmount();
        //额度总和 + 本次授信额度
        totalAmount = AmtUtil.add(totalAmount,zfsqAmount,2);
        //查询核心企业的授信额度
        ZcFinanceProComRel zcFinanceProComRel = iZcFinanceProComRelService.getById(zfsqCoreQuotaId);
        String zfpcrAmount = zcFinanceProComRel.getZfpcrAmount();
        //此核心企业下的供应商授信额度 > 核心企业的授信额度 => 授信额度已超额
        int result = StringUtils.compare(totalAmount,zfpcrAmount);
        if (result == 1){
            throw new Exception("授信额度已超额");
        }
        zcFinanceSupplierQuota.setUpdateBy(userId);
        zcFinanceSupplierQuota.setUpdateTime(DateUtils.getNowDate());
        return AjaxResult.success();
    }

    /**
     * 删除供应商授信管理信息
     * @param zfsqIds 供应商授信管理主键
     * @return
     * @throws BusinessException
     */
    @PreAuthorize(hasPermi = "supplierCredit:line:remove")
    @Log(title = "供应商授信管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{zfsqIds}")
    public AjaxResult delete(@PathVariable String zfsqIds) throws BusinessException {
        ZcFinanceSupplierQuota zcFinanceSupplierQuota = new ZcFinanceSupplierQuota();
        //查询当前操作员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser user = userInfo.getSysUser();
        String userId = user.getUserId() + "";
        //主键
        zcFinanceSupplierQuota.setZfsqId(zfsqIds);
        //状态(00:有效 01:失效 99:删除)
        zcFinanceSupplierQuota.setZfsqStatus("99");
        //修改人
        zcFinanceSupplierQuota.setUpdateBy(userId);
        //修改时间
        zcFinanceSupplierQuota.setUpdateTime(DateUtils.getNowDate());
        iZcFinanceSupplierQuotaService.updateZcFinanceSupplierQuota(zcFinanceSupplierQuota);
        return AjaxResult.success();
    }

    /**
     * 供应商授信管理 冻结/解冻
     * @param zcFinanceSupplierQuota
     * @return
     * @throws Exception
     */
    @PreAuthorize(hasPermi = "supplierCredit:line:update")
    @Log(title = "供应商授信管理", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody ZcFinanceSupplierQuota zcFinanceSupplierQuota) throws Exception
    {
        //授信id
        String zfsqId = zcFinanceSupplierQuota.getZfsqId();
        //授信状态
        String zfsqStatus = zcFinanceSupplierQuota.getZfsqStatus();
        LambdaQueryWrapper<ZcFinanceInf> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZcFinanceInf::getZfiSupplierQuotaId,zfsqId);
        List<ZcFinanceInf> list = zcFinanceInfService.findZcFinanceInfs(queryWrapper);
        String zfiAmount = "0.00";
        if (list.size() > 0){
             zfiAmount = list.get(0).getZfiAmount();
        }
        int result = CommonUtil.compare("0",zfiAmount);
        //判断状态(如果是冻结操作判断是否符合冻结条件
        if ("00".equals(zfsqStatus)) {
            if (result == 0) {
                zcFinanceSupplierQuota.setZfsqStatus("01");
                iZcFinanceSupplierQuotaService.updateZcFinanceSupplierQuota(zcFinanceSupplierQuota);
            }else {
                throw new Exception("此授信正在使用无法冻结");
            }
        }else {
            zcFinanceSupplierQuota.setZfsqStatus("00");
            iZcFinanceSupplierQuotaService.updateZcFinanceSupplierQuota(zcFinanceSupplierQuota);
        }
        return AjaxResult.success();
    }

    /**
     * 模板导出
     * @param response
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response)
    {
        String sheetName = "个税表模板";
        String fileName = "个税表模板";
        //行宽度
        List<Integer> columnWidth = new ArrayList<>();
        List<String> list = new ArrayList<>();
        //列表表头
        List<String> columnName = new ArrayList<>();
        columnName.add("企业名称");
        columnName.add("企业统一社会信用代码");
        columnName.add("授信额度");
        int columnNumber = columnName.size();
        for(String width:columnName){
            columnWidth.add(20);
        }
        try {
            HSSFWorkbook wb = ExcelFileUtils.exportNoResponse(sheetName, fileName,
                    columnNumber, columnWidth, columnName, list);
            response.setCharacterEncoding("UTF-8");
            // 设置contentType为excel格式
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            //默认Excel名称
            response.setHeader("Content-disposition", "attachment;filename=" + "个税表模板"+ URLEncoder.encode(fileName + ".xls", "UTF-8"));
            response.flushBuffer();
            OutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException var) {
                    var.printStackTrace();
                }
            }
        } catch (Exception varLog) {
            log.error("导出Excel异常{}", varLog.getMessage());
        }
    }

    /**
     * 供应商授信导入
     * @param zfpcrId 核心企业授信额度ID
     * @param zfpcrCompanyId 核心企业id
     * @param file
     * @return
     * @throws Exception
     */
    @Log(title = "供应商授信管理", businessType = BusinessType.IMPORT)
    @PreAuthorize(hasAnyPermi = "supplierCredit:line:importData")
    @Transactional(rollbackFor=Exception.class)
    @PostMapping("/importData/{zfpcrId}/{zfpcrCompanyId}")
    public AjaxResult importData(@PathVariable String zfpcrId,@PathVariable String zfpcrCompanyId, MultipartFile file) throws Exception
    {
        //列表对应字段
        List<String> columnName = new ArrayList<>();
        columnName.add("scyName");
        columnName.add("scySocialCode");
        columnName.add("zfsqAmount");
        //excel数据
        List<Map<String,String>> templateData = ExcelFileUtils.readExecleasy(file,columnName,1);
        if(templateData.size() == 0){
            return AjaxResult.error("导入数据不能为空");
        }
        //获取当前操作人员
        LoginUser userInfo = tokenService.getLoginUser();
        SysUser user = userInfo.getSysUser();
        String userId = user.getUserId() + "";
        //供应商授信集合
        List<ZcFinanceSupplierQuota> taxTotalList = new ArrayList<>();
        //返回结果信息
        int failureNum = 0;
        //循环处理excel数据
        for (int i = 0; i < templateData.size(); i++){
            Map<String,String> map = templateData.get(i);
            LambdaQueryWrapper<SysCompany> queryWrapper = new LambdaQueryWrapper<>();
            //企业名称
            String scyName = CommonUtil.objToString(map.get("scyName"));
            //企业统一代码
            String scySocialCode = CommonUtil.objToString(map.get("scySocialCode"));
            //授信额度
            String zfsqAmount = CommonUtil.objToString(map.get("zfsqAmount"));
            if(CommonUtil.isEmpty(scyName)){
                    failureNum++;
                    throw new Exception("<br/>第" + (i+1) + "行数据企业名称为空") ;
            }
            if(CommonUtil.isEmpty(scySocialCode)){

                    failureNum++;
                    throw new Exception("<br/>第" + (i+1) + "行数据企业统一代码为空") ;

            }
            //查询此企业是否存在
            queryWrapper.eq(SysCompany::getScyName,scyName);
            queryWrapper.eq(SysCompany::getScySocialCode,scySocialCode);
            queryWrapper.eq(SysCompany::getScyStatus,"00");
            String scyId = "";
            List<SysCompany> list = iSysCompanyService.findSysCompanys(queryWrapper);
            if(list.size() > 0){
                scyId = list.get(0).getScyId();
            }else {
                failureNum++;
                throw new Exception("<br/>第" + (i+1) + "行数据此企业不存在") ;
            }
            //查询此企业是否为链属关系
            String finalScyId = scyId;
            LambdaQueryWrapper<SysCompanyRel> relWrapper = new LambdaQueryWrapper<>();
            relWrapper.and(j->j.eq(SysCompanyRel::getScrLaunchCompanyId, zfpcrCompanyId).or().eq(SysCompanyRel::getScrReceiveCompanyId,  zfpcrCompanyId));
            relWrapper.and(j->j.eq(SysCompanyRel::getScrLaunchCompanyId, finalScyId).or().eq(SysCompanyRel::getScrReceiveCompanyId, finalScyId));
            relWrapper.ne(SysCompanyRel::getScrStatus,"99");
            List<SysCompanyRel> relList = iSysCompanyRelService.findSysCompanyRels(relWrapper);
            if(relList.size() == 0){
                failureNum++;
                throw new Exception("<br/>第" + (i+1) + "行数据核心企业与此企业暂无建立链属关系") ;
            }
            //查询此企业是否已授信
            LambdaQueryWrapper<ZcFinanceSupplierQuota> supplierWrapper = new LambdaQueryWrapper<>();
            supplierWrapper.eq(ZcFinanceSupplierQuota::getZfsqCompanyId,scyId);
            supplierWrapper.ne(ZcFinanceSupplierQuota::getZfsqStatus,"99");
            int count = iZcFinanceSupplierQuotaService.count(supplierWrapper);
            if (count > 0){
                throw new Exception("此企业已经授信");
            }
            //查询核心企业授信额度ID下的供应商授信额度总和
            QueryWrapper<ZcFinanceSupplierQuota> quotaWrapper = new QueryWrapper<>();
            quotaWrapper.eq("zfsq_core_quota_id",zfpcrId);
            quotaWrapper.eq("zfsq_status","00");
            quotaWrapper.select("IFNULL(CAST(ROUND(SUM(zfsq_amount),2)AS CHAR),'0.00') AS zfsqAmount");
            ZcFinanceSupplierQuota supplierQuota = iZcFinanceSupplierQuotaService.getOne(quotaWrapper);
            String totalAmount = supplierQuota.getZfsqAmount();
            //额度总和 + 本次授信额度
            totalAmount = AmtUtil.add(totalAmount,zfsqAmount,2);
            //查询核心企业的授信额度
            ZcFinanceProComRel zcFinanceProComRel = iZcFinanceProComRelService.getById(zfpcrId);
            String zfpcrAmount = zcFinanceProComRel.getZfpcrAmount();
            //此核心企业下的供应商授信额度 > 核心企业的授信额度 => 授信额度已超额
            int result = StringUtils.compare(totalAmount,zfpcrAmount);
            if (result == 1){
                throw new Exception("授信额度已超额");
            }
            ZcFinanceSupplierQuota zcFinanceSupplierQuota = new ZcFinanceSupplierQuota();
            //主键
            String id = IdUtils.fastSimpleUUID();
            zcFinanceSupplierQuota.setZfsqId(id);
            //核心企业授信额度ID
            zcFinanceSupplierQuota.setZfsqCoreQuotaId(zfpcrId);
            //供应商ID
            zcFinanceSupplierQuota.setZfsqCompanyId(scyId);
            //授信额度
            zcFinanceSupplierQuota.setZfsqAmount(zfsqAmount);
            //状态
            zcFinanceSupplierQuota.setZfsqStatus("00");
            //创建人
            zcFinanceSupplierQuota.setCreateBy(userId);
            //创建时间
            zcFinanceSupplierQuota.setCreateTime(DateUtils.getNowDate());
            taxTotalList.add(zcFinanceSupplierQuota);
        }
        //统一校验完成后再进行数据添加
        //供应商授信额度表
        for(ZcFinanceSupplierQuota inf:taxTotalList){
            iZcFinanceSupplierQuotaService.createZcFinanceSupplierQuota(inf);
        }
        return AjaxResult.success();
    }

    /**
     * 查询核心企业下的链属企业
     * @param zfpcrCompanyId 核心企业id
     * @return
     */
    @GetMapping("listCompanyRel/{zfpcrCompanyId}")
    public AjaxResult listCompanyRel(@PathVariable("zfpcrCompanyId") String zfpcrCompanyId) {
        Map map = new HashMap();
        map.put("companyId",zfpcrCompanyId);
        List<Map> list = supplierCreditLineService.listCompanyRel(map);
        return AjaxResult.success(list);
    }

}

