package com.sifang.modules.order.dao;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.sunshine.SystemSetting.dao.SiteInformationDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmSite;
import com.sifang.modules.sunshine.financialManagement.entity.CrmOrderSiteSettlement;
import com.sifang.modules.order.controller.form.OrderAdjustmentRecord;
import com.sifang.modules.order.entity.CrmOrder;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.MathUtils;
import com.sifang.modules.sys.dao.DjxBaseDao;
import com.sifang.modules.sys.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.*;

@Repository
public class SiteSettlementRecordDao extends DjxBaseDao<CrmOrderSiteSettlement> {

    @Autowired
    OrderDao orderDao;

    @Autowired
    private SiteInformationDao siteDao;

    public void listData(TrimStrMap parasMap, LayuiPage<Record> page) {

        SqlBuilder sb = new SqlBuilder()
                .line("SELECT s.id, s.order_id, s.type,  s.settlement_time, s.create_name, IFNULL(s.service_costs,0) AS service_costs, IFNULL(s.reward_costs,0) AS reward_costs, IFNULL(s.other_cost,0) AS other_cost,  IFNULL(s.mileage_cost,0) AS mileage_cost,  s.remarks, s.site_id, s.jz_flag, s.site_billing_id,o.number,o.site_name,o.warranty_type,o.appliance_category,o.appliance_brand,o.appliance_model,o.service_type," +
                        "SUM(s.service_costs + s.reward_costs + s.other_cost + s.mileage_cost  ) AS total_costs , " +
                        "o.employe_name,service_measures,o.customer_name,o.customer_mobile,o.level,o.customer_telephone,o.order_type,o.province,o.city,o.area,o.customer_address,o.appliance_machine_code,o.power_station_name,b.withdrawal_number,DATE_FORMAT(o.repair_time,'%Y-%m-%d %H:%i:%s') repair_time,DATE_FORMAT(o.end_time,'%Y-%m-%d %H:%i:%s') end_time,o.remarks as orderRemarks,o.appliance_barcode,o.mileage,o.appliance_buy_time  " +
                       " ,b.status as outStatus ,IFNULL((SELECT e.name FROM `crm_platform_employee` e WHERE e.user_id=o.`create_by`),'system')AS createName "+
                        "from crm_order_site_settlement s")
                .line("left join crm_order as o on o.id=s.order_id")
                .line("  LEFT JOIN crm_site_cash_out AS b ON b.id=s.site_billing_id ")
                .line("where 1=1")
                .line(queryCond(parasMap))
                .line(" GROUP BY s.id order by s.settlement_time desc")
                .limit(page.getPage(), page.getLimit());
        List<Record> records = Db.find(sb.build());
        page.setData(records);
        page.setCount(listDataCount(parasMap));
    }

    public Record getTotalCosts(TrimStrMap parasMap){
        StringBuilder sf = new StringBuilder();
        sf.append("  SELECT");
        sf.append(" SUM(s.service_costs) AS service_costs,");
        sf.append(" SUM(s.reward_costs) AS reward_costs,");
        sf.append("  SUM(s.other_cost) AS other_cost,");
        sf.append(" SUM(s.mileage_cost) AS mileage_cost,");
        sf.append(" SUM(s.service_costs + s.reward_costs + s.other_cost + s.mileage_cost  ) AS total_costs ");
        sf.append(" FROM crm_order_site_settlement s ");
        sf.append(" LEFT JOIN crm_order AS o ON o.id=s.order_id  ");
        sf.append("  LEFT JOIN crm_site_cash_out AS b ON b.id=s.site_billing_id ");
        sf.append(" WHERE 1=1 ");
        sf.append(queryCond(parasMap));
        return  Db.findFirst(sf.toString());
    }


    public String queryCond(TrimStrMap parasMap) {
        SqlBuilder sb = new SqlBuilder();

        //服务商名称
        if (parasMap.hasNonBlankValue("siteId")) {
            sb.line("and s.site_id=" + quot(parasMap.get("siteId")));
        }
        //保修类型
        if (parasMap.hasNonBlankValue("warrantyType")) {
            sb.line("and o.warranty_type=" + quot(parasMap.get("warrantyType")));
        }
        //服务类型
        if (parasMap.hasNonBlankValue("serviceType")) {
            sb.line("and o.service_type=" + quot(parasMap.get("serviceType")));
        }
        //产品品类
        if (parasMap.hasNonBlankValue("applianceCategory")) {
            sb.line("and o.appliance_category=" + quot(parasMap.get("applianceCategory")));
        }
        //产品品牌
        if (parasMap.hasNonBlankValue("applianceBrand")) {
            sb.line("and o.appliance_brand=" + quot(parasMap.get("applianceBrand")));
        }
        //产品型号
        if (parasMap.hasNonBlankValue("applianceModel")) {
            sb.line("and o.appliance_model=" + quot(parasMap.get("applianceModel")));
        }
        //请款编号
        if (parasMap.hasNonBlankValue("withdrawalNumber")) {
            sb.line("and b.withdrawal_number like" + likeQuot(parasMap.get("withdrawalNumber").trim()));
        }
        //工单编号
        if (parasMap.hasNonBlankValue("number")) {
            sb.line("and o.number like" + likeQuot(parasMap.get("number").trim()));
        }
        //结算类型
        if (parasMap.hasNonBlankValue("type")) {
            sb.line("and s.type=" + quot(parasMap.get("type")));
        }
        //结账状态
        if (parasMap.hasNonBlankValue("jzFlag")) {
            String flag = parasMap.get("jzFlag");
            if("3".equals(flag)){
                sb.line("and s.jz_flag='0' " );
            }else{
                sb.line("and b.status=" + quot(flag) );
            }
        }
        //电站名称
        if (parasMap.hasNonBlankValue("powerStationName")) {
            sb.line("and o.power_station_name like" + likeQuot(parasMap.get("powerStationName").trim()));
        }
        //用户姓名
        if (parasMap.hasNonBlankValue("customerName")) {
            sb.line("and o.customer_name like" + likeQuot(parasMap.get("customerName").trim()));
        }
        //用户电话
        if (parasMap.hasNonBlankValue("mobile")) {
            String mobile = parasMap.get("mobile").trim();
            sb.line("and (o.customer_mobile like " + likeQuot(mobile) + " or o.customer_telephone like " + likeQuot(mobile) + ")");
        }
        //发布时间
        if (parasMap.hasNonBlankValue("pubStart")) {
            sb.line("and o.repair_time>=" + quot(parasMap.get("pubStart")));
        }
        if (parasMap.hasNonBlankValue("pubEnd")) {
            sb.line("and o.repair_time<" + quot(DateUtils.nextDate(parasMap.get("pubEnd"))));
        }
        //完工时间
        if (parasMap.hasNonBlankValue("endStart")) {
            sb.line("and o.end_time>=" + quot(parasMap.get("endStart")));
        }
        if (parasMap.hasNonBlankValue("end")) {
            sb.line("and o.end_time<" + quot(DateUtils.nextDate(parasMap.get("end"))));
        }
        //结算时间
        if (parasMap.hasNonBlankValue("settlementStart")) {
            sb.line("and s.settlement_time>=" + quot(parasMap.get("settlementStart")));
        }
        if (parasMap.hasNonBlankValue("settlementEnd")) {
            sb.line("and s.settlement_time<" + quot(DateUtils.nextDate(parasMap.get("settlementEnd"))));
        }
        if (parasMap.hasNonBlankValue("billingNo")) {
            sb.line("and b.number=" + quot(parasMap.get("billingNo").trim()));
        }
        //关联服务商结账记录id
        if (parasMap.hasNonBlankValue("site_billing_id")) {
            sb.line("and s.site_billing_id=" + quot(parasMap.get("site_billing_id")));
        }
        //月结账单跳转携带的参数
        if (parasMap.hasNonBlankValue("otherSettlMonth")) {
            sb.line("and DATE_FORMAT(s.settlement_time,'%Y-%m') = " + quot(parasMap.get("otherSettlMonth")));
        }

        return sb.build();
    }


    private long listDataCount(TrimStrMap parasMap) {
        SqlBuilder sb = new SqlBuilder()
                .line("select count(*) as cnt from crm_order_site_settlement s")
                .line("left join crm_order as o on o.id=s.order_id")
                .line("  LEFT JOIN crm_site_cash_out AS b ON b.id=s.site_billing_id ")
                .line("where 1=1")
                .line(queryCond(parasMap));

        return Db.queryLong(sb.toString());
    }

    /**
     * 新增结算调整。
     *
     * 未结账的工单派工结算不可以结算调整。
     *
     */
    public CrmOrderSiteSettlement orderAdjustment(OrderAdjustmentRecord r) {
        CrmOrder order = orderDao.get(r.getOrderId());
        User user = UserUtils.getUser();
        CrmOrderSiteSettlement s = new CrmOrderSiteSettlement();
        s.setOrderId(r.getOrderId());
        s.setType(CrmOrderSiteSettlement.TYPE_ADD);
     /*   s.setServiceMeasures(""); */// 结算调整的时候不填
        s.setSettlementTime(new Date());
        s.setCreateBy(user.getId());
        s.setCreateName(CrmUtils.getUserXM(user));
        s.setServiceCosts(MathUtils.asBigDecimal(r.getServiceCosts()));
        s.setRewardCosts(MathUtils.asBigDecimal(r.getRewardCosts()));
        s.setOtherCost(MathUtils.asBigDecimal(r.getOtherCost()));
        s.setMileageCost(MathUtils.asBigDecimal(r.getMileageCost()));
//        s.setExigencyCosts(new BigDecimal("0.00")); // 没有就存0
       /* s.setExigencyCosts(MathUtils.asBigDecimal(r.getExigencyCosts())); // 没有就存0*/
        s.setCostDetail(""); //结算调整时不存
        s.setRemarks(r.getRemarks());
        s.setSiteId(order.getSiteId());
        s.setJzFlag(CrmOrderSiteSettlement.PRE_JZ_FLAG);
        s.setSiteBillingId(null);
        save(s);
        BigDecimal cost =  MathUtils.sumBigDecimal(s.getServiceCosts(), s.getRewardCosts(), s.getOtherCost(), s.getMileageCost());

        CrmSite site = siteDao.get(s.getSiteId());
        site.setWithdrawableCash(site.getWithdrawableCash().add(cost));
        site.setTotalWallet(site.getTotalWallet().add(cost));
        siteDao.save(site);
        return s;
    }

    public void summaryListData(TrimStrMap parasMap, LayuiPage<Record> page) {
        SqlBuilder sb = new SqlBuilder()
                .line("select s.id from crm_site as s where s.status='0' ")
                .limit(page.getPage(), page.getLimit());




        List<Record> sites = Db.find(sb.toString());
        List<String> siteIds = new ArrayList<>();
        for (Record r : sites) {
            siteIds.add(r.getStr("id"));
        }

        String siteIdsParam = " IN(" + SqlUtils.inParam(siteIds) + ")";
        StringBuffer sf = new StringBuffer();
        sf.append("select count(*) as cnt from crm_site as s where s.status='0' ");
        if (parasMap.hasNonBlankValue("siteId")) {
            siteIdsParam = "=" + quot(parasMap.get("siteId"));
            sf.append(" and s.id " + siteIdsParam + " ");
        }
        long count = Db.queryLong( sf.toString() );

        page.setCount(count);
        // 工单数量的规则是有结算记录并且状态是“5”的工单数量
        sb = new SqlBuilder()
                .line("SELECT s.id,s.name,IFNULL(k.sc,0) as sc,IFNULL(k.rc,0) as rc,IFNULL(k.oc,0) as oc,IFNULL(k.mc,0) as mc,IFNULL(k.wj,0) as wj,IFNULL(k.yj,0) as yj,(IFNULL(k.sc,0)+IFNULL(k.rc,0)+IFNULL(k.oc,0)+IFNULL(k.mc,0)) AS tc,IFNULL(k.cnt,0) AS ordercnt")
                .line("  ,IFNULL((SELECT SUM(ou.withdrawal_amount) FROM crm_site_cash_out ou WHERE ou.STATUS='2' AND ou.site_id = s.id),0) AS siteamount,s.total_wallet   ")
                .line("FROM")
                .line("  (SELECT * FROM crm_site WHERE id" + siteIdsParam + ") AS s")
                .line("  LEFT JOIN")
                .line("  (")
                .line("    SELECT SUM(service_costs) AS sc,SUM(reward_costs) AS rc,SUM(other_cost)AS oc,SUM(mileage_cost) AS mc,s.site_id,COUNT(DISTINCT d.id) AS cnt")
                .line("           ,SUM(CASE WHEN jz_flag='0' THEN (IFNULL(service_costs,0)+IFNULL(reward_costs,0)+IFNULL(other_cost,0)+IFNULL(mileage_cost,0)) ELSE 0 END ) AS wj")
                .line("           ,SUM(CASE WHEN jz_flag='1' THEN (IFNULL(service_costs,0)+IFNULL(reward_costs,0)+IFNULL(other_cost,0)+IFNULL(mileage_cost,0)) ELSE 0 END ) AS yj")
                .line("    FROM `crm_order_site_settlement` as s")
                .line("    INNER JOIN crm_order AS d ON d.id=s.order_id AND d.status='5'")
                .line("    WHERE s.site_id " + siteIdsParam)
                .line(buildQueryCond(parasMap))
                .line("    GROUP BY s.site_id")
                .line("  ) AS k")
                .line("ON k.site_id=s.id");

        List<Record> records = Db.find(sb.build());
        page.setData(records);
    }

    private String buildQueryCond(TrimStrMap parasMap) {
        SqlBuilder sb = new SqlBuilder();
        if (parasMap.hasNonBlankValue("settlementTimeStart")) {
            sb.line("and s.settlement_time>=" + quot(parasMap.get("settlementTimeStart")));
        }
        if (parasMap.hasNonBlankValue("settlementTimeEnd")) {
            sb.line("and s.settlement_time<" + quot(DateUtils.nextDate(parasMap.get("settlementTimeEnd"))));
        }
        return sb.build();
    }

    /**
     * 服务商结算统计合计列
     */
    public Map<String, Object> totalRowData(TrimStrMap parasMap) {
        // 工单数量的规则是有结算记录并且状态是“5”的工单数量
        Map<String, Object> ret = new HashMap<>();

        SqlBuilder sb = new SqlBuilder()
                .line("select s.id from crm_site as s where s.status='0' order by s.create_time desc");

        List<Record> sites = Db.find(sb.toString());
        List<String> siteIds = new ArrayList<>();
        for (Record r : sites) {
            siteIds.add(r.getStr("id"));
        }

        String siteIdsParam = " IN(" + SqlUtils.inParam(siteIds) + ")";
        if (parasMap.hasNonBlankValue("siteId")) {
            siteIdsParam = "=" + quot(parasMap.get("siteId"));
        }



        SqlBuilder sb1 = new SqlBuilder()
                .line("SELECT SUM(service_costs) AS sc,SUM(reward_costs) AS rc,SUM(other_cost)AS oc,SUM(mileage_cost)AS mc,COUNT(DISTINCT d.id) AS cnt")
                .line(",SUM(CASE WHEN jz_flag='0' THEN (IFNULL(service_costs,0)+IFNULL(reward_costs,0)+IFNULL(other_cost,0)+IFNULL(mileage_cost,0)) ELSE 0 END ) AS wj")
                .line(",SUM(CASE WHEN jz_flag='1' THEN (IFNULL(service_costs,0)+IFNULL(reward_costs,0)+IFNULL(other_cost,0)+IFNULL(mileage_cost,0)) ELSE 0 END ) AS yj")
                .line("FROM `crm_order_site_settlement` AS s")
                .line("INNER JOIN crm_order AS d ON d.id=s.order_id AND d.status='5'")
                .line("    WHERE s.site_id " + siteIdsParam)
                .line(buildQueryCond(parasMap));
               /* .line("    GROUP BY s.site_id");*/

        Record rec = Db.findFirst(sb1.toString());
        ret.put("sc" , trimNull(rec.getBigDecimal("sc"))); // 服务费
        ret.put("rc" , trimNull(rec.getBigDecimal("rc"))); // 奖惩费
        ret.put("oc" , trimNull(rec.getBigDecimal("oc"))); // 其他费
        ret.put("mc" , trimNull(rec.getBigDecimal("mc"))); // 里程费
        ret.put("ec" , trimNull(rec.getBigDecimal("ec"))); // 加急费


        ret.put("wj" , trimNull(Db.queryBigDecimal("SELECT SUM(total_wallet) AS wt FROM crm_site WHERE STATUS='0' AND id  "+siteIdsParam ))); // 未请款
        ret.put("yj" , trimNull(Db.queryBigDecimal("SELECT SUM(withdrawal_amount) AS yt FROM crm_site_cash_out WHERE STATUS='2'AND site_id  "+siteIdsParam ))); // 已请款
        ret.put("orderCnt" , rec.getLong("cnt"));
        ret.put("tc" , MathUtils.sumBigDecimal(rec.getBigDecimal("sc"), rec.getBigDecimal("rc"), rec.getBigDecimal("oc"), rec.getBigDecimal("mc"), rec.getBigDecimal("ec")));
        return ret;
    }

    private static BigDecimal trimNull(BigDecimal b) {
        return b == null ? new BigDecimal("0") : b;
    }


    public CrmOrderSiteSettlement getByorderId(String orderId){
         return getByHql("from CrmOrderSiteSettlement where orderId = :p1 and type ='0' ",new Parameter(orderId));
    }


  public List<Record> getUpdateByorderId(String orderId){
        String sql="select * from crm_order_site_settlement where order_id =? and type='1' ";
         return Db.find(sql,orderId);

  }

}
