package com.sifang.modules.order.service;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.sunshine.SystemSetting.dao.CrmOrderSiteSettlementTemplateDao;
import com.sifang.modules.sunshine.SystemSetting.dao.SiteInformationDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmSite;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sunshine.financialManagement.entity.CrmOrderSiteSettlement;
import com.sifang.modules.order.controller.form.OrderAdjustmentRecord;
import com.sifang.modules.order.dao.OrderDao;
import com.sifang.modules.order.dao.OrderOperationInfoDao;
import com.sifang.modules.order.dao.SiteSettlementRecordDao;
import com.sifang.modules.order.entity.CrmOrder;
import com.sifang.modules.order.entity.CrmOrderOperationInfo;
import com.sifang.modules.order.utils.Target;
import com.sifang.modules.order.utils.WebPageFunUtils;
import com.sifang.modules.supply.order.constant.ApplyOrderConstants;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.MathUtils;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import com.sifang.modules.sys.util.TrimStrMap;
import org.hibernate.SQLQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SiteSettlementRecordService extends BaseService {

    @Autowired
    SiteSettlementRecordDao siteSettlementRecordDao;
    @Autowired
    OrderDao orderDao;

    @Autowired
    private CrmOrderSiteSettlementTemplateDao crmSiteSetDao;

    @Autowired
    private OrderOperationInfoDao infoDao;
    @Autowired
    private SiteInformationDao siteDao;

    public void listData(TrimStrMap parasMap, LayuiPage<Record> page) {
        siteSettlementRecordDao.listData(parasMap, page);
    }

    //服务商结算根据id获取结算数据
    public Record getCostById(String id){
        String sql= "SELECT service_costs,reward_costs,exigency_costs,other_cost,mileage_cost FROM `crm_order_site_settlement` WHERE id=?";
        Record record=Db.findFirst(sql,id);
        return record;
    }

    /**
     * 服务商结算，计算工单结算总金额。
     */
    public BigDecimal calcOrderTotalCost(Record settlement) {
        return MathUtils.sumBigDecimal(settlement.getBigDecimal("service_costs"), settlement.getBigDecimal("reward_costs"), settlement.getBigDecimal("other_cost"), settlement.getBigDecimal("mileage_cost"), settlement.getBigDecimal("exigency_costs"));
    }

    /**
     * 结算调整。
     * 未结账的工单派工结算不可以结算调整。
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<Void> orderAdjustment(OrderAdjustmentRecord r) {
        CrmOrderSiteSettlement s = siteSettlementRecordDao.get(r.getId());
        if (CrmOrderSiteSettlement.TYPE_NEW.equals(s.getType()) && CrmOrderSiteSettlement.PRE_JZ_FLAG.equals(s.getJzFlag())) {
            return Result.fail("422" , "unsupported adjustment");
        }

        // 创建结算记录
        CrmOrderSiteSettlement settlement = siteSettlementRecordDao.orderAdjustment(r);
     /*   BigDecimal cost =  MathUtils.sumBigDecimal(settlement.getServiceCosts(), settlement.getRewardCosts(), settlement.getOtherCost(), settlement.getMileageCost(), settlement.getExigencyCosts());
*/
        // 更新工单表  服务商结算费
        SqlBuilder sb = new SqlBuilder()
                .line("update crm_order")
                .line("set site_cost=site_cost+:cost")
                .line("where id=:id");

        SQLQuery sqlQuery = siteSettlementRecordDao.getSession().createSQLQuery(sb.toString());
      /*  sqlQuery.setBigDecimal("cost",cost);*/
        sqlQuery.setParameter("id", r.getOrderId());
        sqlQuery.executeUpdate();

        // 更新工单表中的平台利润
        sb = new SqlBuilder()
                .line("update crm_order")
                .line("set profit=factory_cost-site_cost")
                .line("where id=:id");

        sqlQuery = siteSettlementRecordDao.getSession().createSQLQuery(sb.toString());
        sqlQuery.setParameter("id", r.getOrderId());
        sqlQuery.executeUpdate();
        return Result.ok();
    }

    public void summaryListData(TrimStrMap parasMap, LayuiPage<Record> page) {
        siteSettlementRecordDao.summaryListData(parasMap, page);
    }

    public Map<String, Object> totalRowData(TrimStrMap parasMap) {
        return siteSettlementRecordDao.totalRowData(parasMap);
    }


    public Record getSiteSettlementTemplate(CrmOrder order,String serviceStep){
        String setviceType = order.getServiceType();
        String warrType = order.getWarrantyType();
        return crmSiteSetDao.getSiteSettlementTemplate(setviceType,warrType,serviceStep);
    }

    /**
     * 获取结算方案下具体收费项金额
     */
    public List<Record> getSiteTemplateByNumber(String number,String category){
        return crmSiteSetDao.getSiteTemplateByNumber(number,category);
    }


    /**
     * 结算明细汇总统计
     */
    public Record getTotalCosts(TrimStrMap parasMap){
        return siteSettlementRecordDao.getTotalCosts(parasMap);
    }

    /**
     * 保存服务商结算
     */
    @Transactional(rollbackFor = Exception.class)
    public Result saveSiteSettlement(CrmOrderSiteSettlement sett ,Map<String,String> map){
        logger.info("平台给服务商结算 CrmOrderSiteSettlement" +sett.toString());
        Result result = new Result();
        BigDecimal sero = new BigDecimal("0");
        BigDecimal amount = sett.getMileageCost().add(sett.getOtherCost()).add(sett.getRewardCosts()).add(sett.getServiceCosts());

        String orderId = map.get("orderId");
        CrmOrder order = orderDao.get(orderId);
        if(!CrmOrder.FOUR.equals(order.getStatus())){
            //不在待结算状态下
            result.setCode("409");
            return result;
        } else if(!ApplyOrderConstants.WARRANTY_TYPE_ONE.equals(order.getWarrantyFlag()) && ApplyOrderConstants.SERVICE_TYPE_AZ.equals(order.getServiceType())){
          //未生成保修卡 不能结算
            result.setCode("408");
            return result;
        }
        User user = UserUtils.getUser();
        String name = CrmUtils.getUserXM(user);
        String content = "平台已结算";
        Target ta = new Target();
        ta.setD(DateUtils.getDateTime());
        ta.setP(name);
        ta.setT(18);

        order.setLatestProcess("平台结算工单");
        order.setLatestProcessTime(new Date());
        order.setSiteCost(amount);
        order.setSiteStatus(ApplyOrderConstants.SITE_STATUS_FINISH);
        order.setStatus(ApplyOrderConstants.ORDER_STATUS_FINISH);
        orderDao.save(order);

        sett.setOrderId(map.get("orderId"));
        sett.setType("0");
        sett.setSettlementTime(new Date());
        sett.setCreateBy(user.getId());
        sett.setCreateName(CrmUtils.getUserXM(user));
        sett.setJzFlag(ApplyOrderConstants.JZ_FLAG_NO);
        sett.setSiteId(order.getSiteId());
        siteSettlementRecordDao.save(sett);

        //更新服务商可请款金额
        CrmSite site = siteDao.get(order.getSiteId());
        logger.info("平台给服务商结算  前金额：TotalWallet :{},WithdrawableCash :{}",site.getTotalWallet(),site.getWithdrawableCash());
        site.setTotalWallet(site.getTotalWallet().add(amount));
        site.setWithdrawableCash(site.getWithdrawableCash().add(amount));
        siteDao.save(site);

        logger.info("平台给服务商结算 后金额：TotalWallet :{},WithdrawableCash :{}",site.getTotalWallet(),site.getWithdrawableCash());
        //过程信息
        CrmOrderOperationInfo info = infoDao.getOperaByOrderId(orderId);
        ta.setC(name+content);
        String str = WebPageFunUtils.appendOrderProcessDetail(ta, info.getProcessDetail());
        info.setProcessDetail(str);
        infoDao.save(info);
        result.setCode("200");
        return result;
    }


    /**
     * 保存平台给服务商重新结算
     */
    @Transactional(rollbackFor = Exception.class)
    public Result saveAgainSettlementOrder(CrmOrderSiteSettlement sett ,Map<String,String> map){
        Result result = new Result();
        //验证必填项
        if(StringUtil.isBlank(sett.getId())){
            return Result.fail("400","数据有误，id为空");
        }
        CrmOrderSiteSettlement aga = siteSettlementRecordDao.get(sett.getId());
        //如果已经结账则不可重新结算
        if(!ApplyOrderConstants.JZ_FLAG_NO.equals(aga.getJzFlag())){
            return Result.fail("500","已申请结账，不能重新结算！！");
        }
        BigDecimal before = new BigDecimal("0.00");
        BigDecimal amount = sett.getMileageCost().add(sett.getOtherCost()).add(sett.getRewardCosts()).add(sett.getServiceCosts());
        User user = UserUtils.getUser();
        if(aga !=null){
            logger.info(" 平台给服务商重新结算 orderId: "+aga.getOrderId());
            before = aga.getMileageCost().add(aga.getOtherCost()).add(aga.getRewardCosts()).add(aga.getServiceCosts());
            CrmOrder order = orderDao.get(aga.getOrderId());
            order.setLatestProcessTime(new Date());
            order.setLatestProcess("平台给服务商重新结算 ");
            order.setSiteCost(amount);
            orderDao.save(order);
           /* aga.setServiceStep(sett.getServiceStep());*/
           /* aga.setServiceCosts(sett.getServiceCosts());*/
            aga.setRewardCosts(sett.getRewardCosts());
            aga.setOtherCost(sett.getOtherCost());
         /*   aga.setMileageCost(sett.getMileageCost());*/
            aga.setRemarks(sett.getRemarks());
            aga.setSettlementTime(new Date());
            aga.setCostDetail(user.getLoginName()+"重新结算");
            siteSettlementRecordDao.save(aga);

            String name = CrmUtils.getUserXM(user);
            String content = "平台给服务商已重新结算";
            Target ta = new Target();
            ta.setD(DateUtils.getDateTime());
            ta.setP(name);
            ta.setT(21);
            //过程信息
            CrmOrderOperationInfo info = infoDao.getOperaByOrderId(aga.getOrderId());
            ta.setC(name+content);
            String str = WebPageFunUtils.appendOrderProcessDetail(ta, info.getProcessDetail());
            info.setProcessDetail(str);
            infoDao.save(info);
            //更新服务商可请款金额
            CrmSite site = siteDao.get(order.getSiteId());
            logger.info(user.getLoginName()+"重新结算前金额 ， TotalWallet:{},WithdrawableCash: {}",site.getTotalWallet(),site.getWithdrawableCash() );
            site.setTotalWallet(site.getTotalWallet().subtract(before).add(amount));
            site.setWithdrawableCash(site.getWithdrawableCash().subtract(before).add(amount));
            siteDao.save(site);
            logger.info(user.getLoginName()+"重新结算后金额 ， TotalWallet:{},WithdrawableCash: {}",site.getTotalWallet(),site.getWithdrawableCash() );
            result.setCode("200");
        }
        return result;
    }


    /**
     * 获取服务商结算数据
     */
    public Record getOrderSettle(String orderId){
        String sql = " SELECT * FROM `crm_order_site_settlement` a WHERE a.order_id=? AND a.type='0' LIMIT 1   ";
        Record rds = Db.findFirst(sql,orderId);
        return rds;
    }

    /**
     * 获取服务商结算明细总额
    */
    public Record getOrderSiteSettleSum(String orderId){
        String sql = "SELECT a.order_id,a.service_measures,a.type,a.settlement_time,a.create_name,SUM(a.service_costs) AS service_costs,SUM(a.reward_costs) AS reward_costs,SUM(a.other_cost) AS other_cost,SUM(a.mileage_cost) AS mileage_cost,SUM(a.exigency_costs) AS exigency_costs,a.remarks ,a.jz_flag FROM crm_order_site_settlement a WHERE a.order_id=? AND a.type='0' LIMIT 1   ";
        Record rds = Db.findFirst(sql,orderId);
        return rds;
    }

    /***
     * 工单的收款信息
     */
public Record getOrderCollection(String orderId){
   Record rd=Db.findFirst("SELECT GROUP_CONCAT(c.imgs SEPARATOR ',') AS imgs,SUM(payment_amount) as amount FROM `crm_order_collections` c WHERE c.order_id=? AND c.status='0' ",orderId);
    return rd;
}
}
