package cn.superdesk.uniorder.dubbo.provider.accounting.operator;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.accounting.operator.AccountingEmailStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.operator.AccountingOrderOperatorAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.unified.operator.AccountingUnifiedOperatorWithBLOBs;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedCustomerInvoiceTitle;
import cn.superdesk.uniorder.dao.entity.operationCenter.accounting.UnifiedAccountingOrderGoods;
import cn.superdesk.uniorder.dao.entity.operationCenter.accounting.UnifiedAccountingOrderGoodsExample;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dao.entity.unified.settlement.UnifiedSettlementProgramme;
import cn.superdesk.uniorder.dao.mapper.operationCenter.accounting.UnifiedAccountingOrderGoodsMapper;
import cn.superdesk.uniorder.dao.mapper.operationCenter.accounting.UnifiedAccountingOrderGoodsMapperEx;
import cn.superdesk.uniorder.dto.param.accounting.unified.operator.AccountingUnifiedOperatorQueryParam;
import cn.superdesk.uniorder.dto.vo.accounting.unified.operator.*;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OperationCenterBillStartVo;
import cn.superdesk.uniorder.dubbo.facade.accounting.operator.DubboAccountingUnifiedOperatorService;
import cn.superdesk.uniorder.dubbo.facade.sys.notify.DubboSysNotifyService;
import cn.superdesk.uniorder.service.accounting.unified.operator.AccountingUnifiedOperatorService;
import cn.superdesk.uniorder.service.operationCenter.OperationCenterBillStartService;
import cn.superdesk.uniorder.service.operationCenter.UnifiedAccountingOrderGoodsService;
import cn.superdesk.uniorder.service.sys.SysUserService;
import cn.superdesk.uniorder.service.unified.settlement.UnifiedSettlementProgrammeService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service(version = "1.0.1", retries = -1, timeout = 30000)
public class DubboAccountingUnifiedOperatorServiceImpl implements DubboAccountingUnifiedOperatorService {

    @Reference(version = "1.0.0", timeout = 10000, retries = -1)
    private DubboSysNotifyService dubboSysNotifyService;
    @Autowired
    private AccountingUnifiedOperatorService accountingUnifiedOperatorService;

    @Autowired
    private UnifiedAccountingOrderGoodsMapper unifiedAccountingOrderGoodsMapper;
    @Autowired
    private SysUserService sysUserService;

    @Override
    public String exportAccountSupplierList(AccountingUnifiedOperatorQueryParam param, LoginSysUser loginSysUser) {
        log.info("运营中心-账单管理-导出账单（含供应商成本） exportList params: \n{}", JSON.toJSONString(param));
        CompletableFuture.runAsync(() -> {
            try {
                SysNotify sysNotify = accountingUnifiedOperatorService.exportAccountSupplierList(param);
                // 通知
                dubboSysNotifyService.notifyExportExcelScoreOrderReconciliationNotYet(sysNotify, loginSysUser);
            } catch (Exception e) {
                log.error("运营中心-账单管理-导出账单（含供应商成本） exportList {} -> 执行 异常:{}", AnJsonUtils.toJson(param), e);
            }
        });
        return "导出任务已经接收,正在处理中...";
    }

    @Override
    public String exportAccountList(AccountingUnifiedOperatorQueryParam param, LoginSysUser loginSysUser) {
        log.info("运营中心-账单管理-导出账单 exportList params: \n{}", JSON.toJSONString(param));
        CompletableFuture.runAsync(() -> {
            try {
                SysNotify sysNotify = accountingUnifiedOperatorService.exportAccountList(param);
                // 通知
                dubboSysNotifyService.notifyExportExcelScoreOrderReconciliationNotYet(sysNotify, loginSysUser);
            } catch (Exception e) {
                log.error("运营中心-账单管理-导出账单 exportList {} -> 执行 异常:{}", AnJsonUtils.toJson(param), e);
            }
        });
        return "导出任务已经接收,正在处理中...";
    }

    @Override
    public String exportList(AccountingUnifiedOperatorQueryParam param, LoginSysUser loginSysUser) {
        log.info("运营中心-账单管理-导出列表 exportList params: \n{}", JSON.toJSONString(param));
        CompletableFuture.runAsync(() -> {
            try {
                SysNotify sysNotify = accountingUnifiedOperatorService.exportList(param);
                // 通知
                dubboSysNotifyService.notifyExportExcelScoreOrderReconciliationNotYet(sysNotify, loginSysUser);
            } catch (Exception e) {
                log.error("运营中心-账单管理-导出列表 exportList {} -> 执行 异常:{}", AnJsonUtils.toJson(param), e);
            }
        });
        return "导出任务已经接收,正在处理中...";
    }

    @Override
    public R<AccountingBillVo> getById(Long id) {
        return new R(accountingUnifiedOperatorService.getBillVo(id));
    }

    @Override
    public R<List<AccountingUnifiedOperatorVo>> getList(AccountingUnifiedOperatorQueryParam param) {
        PageHelper.startPage(param.getPageNumber(), param.getPageSize());
        List<AccountingUnifiedOperatorVo> list = getAccountingList(param);
        PageInfo<AccountingUnifiedOperatorVo> page = new PageInfo<>(list);
        return new R<List<AccountingUnifiedOperatorVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), list);
    }

    @Override
    public List<AccountingUnifiedOperatorVo> getAccountingList(AccountingUnifiedOperatorQueryParam param) {
        return accountingUnifiedOperatorService.getAccountingList(param);
    }

    @Override
    public R<AccountingBillBaseVo> getBaseBillInfo(Long billId) {
        return new R<>(accountingUnifiedOperatorService.getBaseBillInfo(billId));
    }

    @Override
    public R<String> confirmBill(Long billId,String accountingOrderSn,Long userId) {

        //修改账单状态为已确定
        AccountingUnifiedOperatorWithBLOBs entity = new AccountingUnifiedOperatorWithBLOBs();
        entity.setId(billId);
        entity.setAccountingStatus((byte) 4);//已确认
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(userId);
        accountingUnifiedOperatorService.updateByPrimaryKeySelective(entity);
        //将该账单的 流水数据和商品数据 更改 已对账
        UnifiedAccountingOrderGoodsExample example = new UnifiedAccountingOrderGoodsExample();
        example.createCriteria().andAccountingOrderSnOperatorEqualTo(accountingOrderSn);
        UnifiedAccountingOrderGoods record = new UnifiedAccountingOrderGoods();
        record.setAccountingStatus(CommonAccountingStateEnum.已对账.getKey());//修改订单为 已对账
        unifiedAccountingOrderGoodsMapper.updateByExampleSelective(record, example);


        log.info("用户id为：{},确认账单id为：{}---确认账单！", userId, billId);

        return new R<>("确认账单成功！");
    }

    @Override
    public R<String> cancelBill(AccountingUnifiedOperatorQueryParam param, Long userId) {


        //修改账单状态为已取消
        AccountingUnifiedOperatorWithBLOBs entity = new AccountingUnifiedOperatorWithBLOBs();
        entity.setId(param.getBillId());
        entity.setAccountingStatus((byte) 6);//已取消
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(userId);
        SysUser user = sysUserService.findById(userId);
        entity.setCancelReason("[" + user.getFullname() + ","
                + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")
                + "]:"
                + param.getReason());
        accountingUnifiedOperatorService.updateByPrimaryKeySelective(entity);
        log.info("用户id为：{},取消账单id为：{}---确认账单！", userId, param.getBillId());

        return new R<>("取消账单成功！");
    }

    @Override
    public R<String> rejectBill(AccountingUnifiedOperatorQueryParam param, Long userId) {

        //修改账单状态为已驳回
        AccountingUnifiedOperatorWithBLOBs entity = new AccountingUnifiedOperatorWithBLOBs();
        entity.setId(param.getBillId());
        entity.setAccountingStatus((byte) 5);//已驳回
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(userId);
        SysUser user = sysUserService.findById(userId);
        entity.setRejectReson("[" + user.getFullname() + ","
                + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")
                + "]:"
                + param.getReason());
        accountingUnifiedOperatorService.updateByPrimaryKeySelective(entity);
        log.info("用户id为：{},驳回账单id为：{}---确认账单！", userId, param.getBillId());

        return new R<>("驳回账单成功！");
    }

    @Override
    public R<String> saveRemark(AccountingUnifiedOperatorQueryParam param, Long userId) {

        //添加备注
        AccountingUnifiedOperatorWithBLOBs entity = new AccountingUnifiedOperatorWithBLOBs();
        entity.setId(param.getBillId());
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(userId);
        entity.setRemark(param.getRemark());
        accountingUnifiedOperatorService.updateByPrimaryKeySelective(entity);
        log.info("用户id为：{},账单id为：{}---备注内容:{}！",userId, param.getBillId(),  param.getRemark());

        return new R<>("添加账单备注成功！");
    }

    @Override
    public R<String> agreeReject(AccountingUnifiedOperatorQueryParam param, Long userId) {
        AccountingUnifiedOperatorWithBLOBs entity = new AccountingUnifiedOperatorWithBLOBs();
        entity.setId(param.getBillId());
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(userId);
        entity.setAccountingStatus((byte)6);
        accountingUnifiedOperatorService.updateByPrimaryKeySelective(entity);
        log.info("用户id为：{},账单id为：{}---同意驳回，更改订单状态为已取消！",userId, param.getBillId());
        return new R<>("同意驳回成功！");
    }
}
