package com.jianshui.platform.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.core.domain.entity.Companyservice;
import com.jianshui.common.core.domain.entity.SysUser;
import com.jianshui.common.core.domain.model.LoginUser;
import com.jianshui.common.exception.jianshui.JianshuiServiceException;
import com.jianshui.common.utils.SecurityUtils;
import com.jianshui.common.utils.ValidateUtils;
import com.jianshui.invoice.domain.Invoice;
import com.jianshui.invoice.domain.InvoiceDetail;
import com.jianshui.invoice.domain.Redinfo;
import com.jianshui.invoice.domain.Redinfodetail;
import com.jianshui.invoice.domain.dto.HXResponse;
import com.jianshui.invoice.factory.IInvoiceServiceFactory;
import com.jianshui.invoice.mapper.InvoiceMapper;
import com.jianshui.invoice.mapper.RedinfoMapper;
import com.jianshui.invoice.service.IInvoiceApiService;
import com.jianshui.platform.constant.ExceptionInformationConstants;
import com.jianshui.platform.constant.RedWordConstants;
import com.jianshui.invoice.domain.dto.FindRedWordDTO;
import com.jianshui.platform.dto.invoicered.RedWordSelectionDTO;
import com.jianshui.platform.dto.invoicered.RedWordDTO;
import com.jianshui.platform.dto.invoicered.RedinfodetailDTO;
import com.jianshui.platform.service.RedInformationService;
import com.jianshui.platform.vo.invoicered.FindRedWordVO;
import com.jianshui.platform.vo.invoicered.PageFindRedWordVO;
import com.jianshui.platform.vo.invoicered.RedWordSelectionVO;
import com.jianshui.system.mapper.CompanyserviceMapper;
import com.jianshui.system.mapper.SysUserMapper;
import com.jianshui.system.service.IServiceManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


/**
 * @Author: kane
 * @Description: 红字信息业务类
 * @CreateTime: 2023-06-21  15:21
 * @Version: 1.0
 **/
@Service
@Slf4j
public class RedInformationServiceImpl implements RedInformationService {

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private RedinfoMapper redinfoMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private CompanyserviceMapper companyserviceMapper;
    @Autowired
    private IServiceManageService serviceManageService;

    @Autowired
    private IInvoiceServiceFactory invoiceServiceFactory;


    /**
     * 功能描述: 红字信息选择
     * @param redWordSelectionDTO
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult redWordSelection(RedWordSelectionDTO redWordSelectionDTO) {
        //判空
        ValidateUtils.validate(redWordSelectionDTO);
        //获取当前用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = sysUserMapper.selectUserById(loginUser.getUserId());
        //根据用户信息获取企业信息
        Companyservice companyservice = companyserviceMapper.selectCompanyserviceByCompanyid(sysUser.getCompanyId());
        //销方类型
        if (RedWordConstants.XFTYPE.equals(redWordSelectionDTO.getSqlx())){
            //空信息响应
            if (redWordSelectionDTO.getFpdm().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.FPDMISEMPTY);
            }
            if (redWordSelectionDTO.getFphm().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.FPHMISEMPTY);
            }
            if (redWordSelectionDTO.getKprq().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.KPRQISEMPTY);
            }
            //查询蓝票信息
            Invoice invoice = invoiceMapper.selectByFpdmFphm(companyservice.getCompanyid(),redWordSelectionDTO.getFpdm(), redWordSelectionDTO.getFphm());
            //明细行数记录
            int count = 0;
            if (invoice != null){
                //封装红字信息选择返回
                RedWordSelectionVO redWordSelectionVO = new RedWordSelectionVO();
                BeanUtils.copyProperties(invoice,redWordSelectionVO);
                List<InvoiceDetail> invoiceDetailList = invoice.getInvoiceDetailList();
                //统计明细行数
                for (InvoiceDetail invoiceDetail : invoiceDetailList) {
                    if (invoiceDetail != null){
                        count++;
                    }
                }
                redWordSelectionVO.setDetailCount(count);
                redWordSelectionVO.setSqlx(redWordSelectionDTO.getSqlx());
                return AjaxResult.success(redWordSelectionVO);
            }
            return AjaxResult.error(ExceptionInformationConstants.NOTINVOICEINFORMATION);
        }else if (RedWordConstants.ISDEDUCTION.equals(redWordSelectionDTO.getSqlx())){
            //购方已抵扣返回类
            RedWordSelectionVO redWordSelectionVO = new RedWordSelectionVO();
            redWordSelectionVO.setBuyerName(companyservice.getSellername());
            redWordSelectionVO.setBuyerTaxnum(companyservice.getSellertax());
            redWordSelectionVO.setSqlx(redWordSelectionDTO.getSqlx());
            return AjaxResult.success(redWordSelectionVO);
        }else if (RedWordConstants.NOTDEDUCTION.equals(redWordSelectionDTO.getSqlx())){
            //空信息响应
            if (redWordSelectionDTO.getFpdm().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.FPDMISEMPTY);
            }
            if (redWordSelectionDTO.getFphm().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.FPHMISEMPTY);
            }
            if (redWordSelectionDTO.getKprq().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.KPRQISEMPTY);
            }
            //购方未抵扣返回类
            RedWordSelectionVO redWordSelectionVO = new RedWordSelectionVO();
            BeanUtils.copyProperties(redWordSelectionDTO,redWordSelectionVO);
            redWordSelectionVO.setBuyerName(companyservice.getSellername());
            redWordSelectionVO.setBuyerTaxnum(companyservice.getSellertax());
            return AjaxResult.success(redWordSelectionVO);
        }else {
            return AjaxResult.error(ExceptionInformationConstants.REQUESTTYPEERROR);
        }
    }

    /**
     * 功能描述: 红字信息提交
     * @param dto
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult redWordSubmit(RedWordDTO dto) {
        //判空
        ValidateUtils.validate(dto);
        //类型判断
        if (RedWordConstants.XFTYPE.equals(dto.getSqlx())){
            //发票信息判断
            if (dto.getOriginFpdm().isEmpty() || dto.getOriginFphm().isEmpty() || dto.getOriginKprq().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.INVOICEINFORMATIONISEMPTY);
            }
            //红字信息保存
            insertRedWord(dto);
        }else if (RedWordConstants.ISDEDUCTION.equals(dto.getSqlx())){
            //红字信息保存
            insertRedWord(dto);
        }else {
            //发票信息判断
            if (dto.getOriginFpdm().isEmpty() || dto.getOriginFphm().isEmpty() || dto.getOriginKprq().isEmpty()){
                return AjaxResult.error(ExceptionInformationConstants.INVOICEINFORMATIONISEMPTY);
            }
            //红字信息保存
            insertRedWord(dto);
        }
        return AjaxResult.success(RedWordConstants.SUBMITSUCCESS);
    }
    /**
     * 功能描述: 红字信息保存
     * @param dto
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    public void insertRedWord(RedWordDTO dto){
        //获取用户信息
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        Companyservice companyservice = companyserviceMapper.selectCompanyserviceByCompanyid(sysUser.getCompanyId());
        //封装红字信息实体类
        Redinfo redinfo = new Redinfo();
        BeanUtils.copyProperties(dto,redinfo);
        if (RedWordConstants.TAXINVOICE.equals(dto.getStatus())){
            //含税总计金额
            redinfo.setTaxamt(dto.getTotalMoney());
            //总计税额
            redinfo.setTax(dto.getTotalTax());
            //不含税总计金额
            redinfo.setTaxfreeamt(dto.getTotalMoney().subtract(dto.getTotalTax()));
        }
        if (RedWordConstants.NOTTAXINVOICE.equals(dto.getStatus())){
            //不含税总计金额
            redinfo.setTaxfreeamt(dto.getTotalMoney());
            //含税总计金额
            redinfo.setTaxamt(dto.getTotalMoney().add(dto.getTotalTax()));
            //总计税额
            redinfo.setTax(dto.getTotalTax());
        }
        //不为空字段
        String uuidhm = UUID.randomUUID().toString();
        redinfo.setSystemOrderno(uuidhm);
        String outOrderNO = uuidhm.replaceAll("-", "");
        redinfo.setOutTradeOrderno(outOrderNO);
        redinfo.setFpqqlsh(uuidhm);
        redinfo.setCompanyId(sysUser.getCompanyId());
        redinfo.setRedInfoStatus("6");
        String serviceKey = null;
        try {
            serviceKey = serviceManageService.getCompanyServiceSupplier("invoice", sysUser.getCompanyId());
            redinfo.setServiceSupplierKey(serviceKey);
        } catch (Exception e) {
            log.error("简税产品端，红字信息提交失败，企业税号={},servicekey={}",companyservice.toString(),serviceKey);
            throw new JianshuiServiceException("红字信息提交异常！");
        }
        //保存红字信息
        redinfoMapper.insertRedinfo(redinfo);
        //封装红字信息详情实体类
        List<RedinfodetailDTO> redinfodetailList = dto.getRedinfodetailList();
        List<Redinfodetail> redinfodetails = new ArrayList<>();
        //行数
        int count = 1;
        for (RedinfodetailDTO redinfodetailDTO : redinfodetailList) {
            //红字信息详情实体类
            Redinfodetail redinfodetail = new Redinfodetail();
            BeanUtils.copyProperties(redinfodetailDTO,redinfodetail);
            redinfodetail.setRedinfoId(redinfo.getId());
            redinfodetail.setIndex(count);
            redinfodetail.setTaxrate(redinfodetailDTO.getTaxrate().divide(new BigDecimal("100"),4,BigDecimal.ROUND_HALF_UP));
            if (RedWordConstants.TAXINVOICE.equals(dto.getStatus())){
                //单价税额
                BigDecimal taxCost = redinfodetailDTO.getTax().divide(redinfodetailDTO.getNum(),2,BigDecimal.ROUND_HALF_UP);
                //不含税单价
                redinfodetail.setPrice(redinfodetailDTO.getCost().subtract(taxCost));
                //含税金额
                redinfodetail.setTaxamt(redinfodetailDTO.getMoney());
                //不含税金额
                redinfodetail.setTaxfreeamt(redinfodetailDTO.getMoney().subtract(redinfodetailDTO.getTax()));
            }else if (RedWordConstants.NOTTAXINVOICE.equals(dto.getStatus())){
                //不含税单价
                redinfodetail.setPrice(redinfodetailDTO.getCost());
                //不含税金额
                redinfodetail.setTaxfreeamt(redinfodetailDTO.getMoney());
                //含税金额
                redinfodetail.setTaxamt(redinfodetailDTO.getMoney().add(redinfodetailDTO.getTax()));
            }
            redinfodetails.add(redinfodetail);
            count++;
        }
        //保存红字信息详情
        redinfoMapper.batchRedinfodetail(redinfodetails);
    }


    /**
     * 功能描述: 红字信息查询
     * @param dto
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult findRedWord(FindRedWordDTO dto) {
        //获取红字信息集合
        PageHelper.startPage(dto.getPageNum(),dto.getPageSize());
        List<Redinfo> redinfoList = redinfoMapper.findRedInfoList(dto);
        PageInfo<Redinfo> pageInfo = new PageInfo<>(redinfoList);
        //封装红字信息集合返回
        List<FindRedWordVO> findRedWordVOS = new ArrayList<>();
        for (Redinfo redinfo : pageInfo.getList()) {
            FindRedWordVO findRedWordVO = new FindRedWordVO();
            BeanUtils.copyProperties(redinfo,findRedWordVO);
            findRedWordVOS.add(findRedWordVO);
        }
        //分页对象
        PageFindRedWordVO pageFindRedWordVO = new PageFindRedWordVO();
        pageFindRedWordVO.setTotal(pageInfo.getTotal());
        pageFindRedWordVO.setRecords(findRedWordVOS);
        return AjaxResult.success(pageFindRedWordVO);
    }

    /**
     * 功能描述: 红字信息明细查询
     * @param id
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult findRedWordDetail(Long id) {
        if (id == null){
            return AjaxResult.error(ExceptionInformationConstants.REDWORDINFOISEMPT);
        }
        Redinfo redinfo = redinfoMapper.selectRedinfoById(id);
        if (redinfo == null){
            return AjaxResult.error(ExceptionInformationConstants.NOTFINREDWORDINFO);
        }
        //封装红字信息返回
        RedWordDTO redWordDTO = new RedWordDTO();
        BeanUtils.copyProperties(redinfo,redWordDTO);
        redWordDTO.setStatus(RedWordConstants.NOTTAXINVOICE);
        redWordDTO.setTotalMoney(redinfo.getTaxfreeamt());
        //封装红字信息详情
        List<Redinfodetail> redinfodetailList = redinfo.getRedinfodetailList();
        List<RedinfodetailDTO> redinfodetailDTOS = new ArrayList<>();
        for (Redinfodetail redinfodetail : redinfodetailList) {
            RedinfodetailDTO redinfodetailDTO = new RedinfodetailDTO();
            BeanUtils.copyProperties(redinfodetail,redinfodetailDTO);
            redinfodetailDTO.setCost(redinfodetail.getPrice());
            redinfodetailDTO.setMoney(redinfodetail.getTaxfreeamt());
            redinfodetailDTOS.add(redinfodetailDTO);
        }
        redWordDTO.setRedinfodetailList(redinfodetailDTOS);
        return AjaxResult.success(redWordDTO);
    }

    /**
     * 功能描述: 批量删除红字信息
     * @param ids
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult deleteRedWord(Long[] ids) {
        if (ids == null || ids.length == 0){
            return AjaxResult.error(ExceptionInformationConstants.REDWORDINFOISEMPT);
        }
        for (Long id : ids) {
            Redinfo redinfo = redinfoMapper.selectRedinfoById(id);
            String redInfoStatus = redinfo.getRedInfoStatus();
            if (!"6".equals(redInfoStatus)){
                return AjaxResult.error(ExceptionInformationConstants.NOTDELETEREDWORD);
            }
        }
        //批量删除
        redinfoMapper.deleteRedinfoByIds(ids);
        redinfoMapper.deleteRedinfodetailByRedinfoIds(ids);
        return AjaxResult.success(RedWordConstants.DELETESUCCESS);
    }

    /**
     * 功能描述: 红字信息修改
     * @param dto
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public AjaxResult updateRedWord(RedWordDTO dto) {
        if (dto.getId() == null){
            return AjaxResult.error(ExceptionInformationConstants.REDWORDINFOISEMPT);
        }
        Redinfo redinfo = redinfoMapper.selectRedinfoById(dto.getId());
        if (redinfo == null){
            return AjaxResult.error(ExceptionInformationConstants.NOTFINREDWORDINFO);
        }
        if ("6".equals(redinfo.getRedInfoStatus()) || "2".equals(redinfo.getRedInfoStatus())){
            BeanUtils.copyProperties(dto,redinfo);
            if (RedWordConstants.TAXINVOICE.equals(dto.getStatus())){
                // 含税总计金额
                redinfo.setTaxamt(dto.getTotalMoney());
                // 总计税额
                redinfo.setTax(dto.getTotalTax());
                // 不含税总计金额
                redinfo.setTaxfreeamt(dto.getTotalMoney().subtract(dto.getTotalTax()));
            }
            if (RedWordConstants.NOTTAXINVOICE.equals(dto.getStatus())){
                // 不含税总计金额
                redinfo.setTaxfreeamt(dto.getTotalMoney());
                // 含税总计金额
                redinfo.setTaxamt(dto.getTotalMoney().add(dto.getTotalTax()));
                // 总计税额
                redinfo.setTax(dto.getTotalTax());
            }
            redinfoMapper.updateRedinfo(redinfo);
            // 红字信息详情
            List<RedinfodetailDTO> redinfodetailList = dto.getRedinfodetailList();
            List<Redinfodetail> redinfodetails = new ArrayList<>();
            int count = 1;
            for (RedinfodetailDTO redinfodetailDTO : redinfodetailList) {
                //删除详情表
                redinfoMapper.deleteRedinfodetailByRedinfoId(dto.getId());
                Redinfodetail redinfodetail = new Redinfodetail();
                BeanUtils.copyProperties(redinfodetailDTO,redinfodetail);
                redinfodetail.setRedinfoId(redinfo.getId());
                redinfodetail.setIndex(count);
                redinfodetail.setTaxrate(redinfodetailDTO.getTaxrate().divide(new BigDecimal("100"),4,BigDecimal.ROUND_HALF_UP));
                if (RedWordConstants.TAXINVOICE.equals(dto.getStatus())){
                    //单价税额
                    BigDecimal taxCost = redinfodetailDTO.getTax().divide(redinfodetailDTO.getNum(),2,BigDecimal.ROUND_HALF_UP);
                    //不含税单价
                    redinfodetail.setPrice(redinfodetailDTO.getCost().subtract(taxCost));
                    //含税金额
                    redinfodetail.setTaxamt(redinfodetailDTO.getMoney());
                    //不含税金额
                    redinfodetail.setTaxfreeamt(redinfodetailDTO.getMoney().subtract(redinfodetailDTO.getTax()));
                }else if (RedWordConstants.NOTTAXINVOICE.equals(dto.getStatus())){
                    //不含税单价
                    redinfodetail.setPrice(redinfodetailDTO.getCost());
                    //不含税金额
                    redinfodetail.setTaxfreeamt(redinfodetailDTO.getMoney());
                    //含税金额
                    redinfodetail.setTaxamt(redinfodetailDTO.getMoney().add(redinfodetailDTO.getTax()));
                }
                redinfodetails.add(redinfodetail);
                count++;
            }
            redinfoMapper.batchRedinfodetail(redinfodetails);
            return AjaxResult.success(RedWordConstants.SUBMITSUCCESS);
        }else {
            return AjaxResult.error(ExceptionInformationConstants.NOTUPDATEREDWORD);
        }
    }

    /**
     * 功能描述: 红字信息表上传
     * @param id
     * @return : com.jianshui.common.core.domain.AjaxResult
     */
    @Override
    public HXResponse uploadRedWord(Long id) {
        // TODO 暂未开发完成
        if (id == null){
            return new HXResponse(ExceptionInformationConstants.REDWORDINFOISEMPT);
        }
        Redinfo redinfo = redinfoMapper.selectRedinfoById(id);
        if (redinfo == null){
            return new HXResponse(ExceptionInformationConstants.NOTFINREDWORDINFO);
        }
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        Companyservice companyservice = companyserviceMapper.selectCompanyserviceByCompanyid(sysUser.getCompanyId());
        String serviceKey = null;
        HXResponse result;
        try {
            serviceKey = serviceManageService.getCompanyServiceSupplier("invoice", sysUser.getCompanyId());
            IInvoiceApiService invoiceService = invoiceServiceFactory.getService(serviceKey);
            result = invoiceService.uploadRedInfo(redinfo, companyservice);
        } catch (Exception e) {
            log.error("简税产品端，红字信息上传失败，企业税号={},servicekey={}",companyservice.toString(),serviceKey);
            throw new JianshuiServiceException("红字信息上传异常！");
        }
        return result;
    }

}
