package com.sifang.modules.customer.dao;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.customer.constant.UserConstants;
import com.sifang.modules.customer.entity.CrmCustomerContractManagement;
import com.sifang.modules.site.siteInfo.service.SiteEmployeeService;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.dao.UserDao;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import org.hibernate.SQLQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Repository
public class ContractManagementDao extends BaseDao<CrmCustomerContractManagement> {

    @Autowired
    UserDao userDao;

    @Autowired
    SiteEmployeeService siteEmployeeService;

    Logger logger = LoggerFactory.getLogger(getClass());

    public List<Record> smallProgramGetList(LayuiPage<Record> page, Map<String, String> map, Operator operator) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT cm.project_company_name AS companyName, e.`project_name` AS projectName, ")
                .line(" cm.contract_number AS contractNumber, cm.id,")
                .line(" cm.`power_station_code` AS powerStationCode, e.`trader_name` AS traderName")
                .line("FROM crm_customer_contract_management cm")
                .line("INNER JOIN crm_customer_entry e ON e.id = cm.entry_id")
                .line("WHERE cm.status != '0' ");
        appendCondition(builder, map,operator);
        builder.line("ORDER BY cm.invitation_time desc")
                .limit(page.getPage(), page.getLimit());
        return Db.find(builder.build(), builder.params());
    }

    public List<Record> selectList(LayuiPage<Record> page, Map<String, String> map, Operator operator) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT cm.id as contractId , e.id ,cm.contract_number, cm.contract_number AS contractNumber, cm.status,cm.power_station_code, cm.power_station_code AS powerStationCode,")
                .line(" DATE_FORMAT(cm.tenant_sign_time,'%Y-%m-%d') as tenantSignTime,")
                .line(" e.mobile AS tenantMobile,e.mobile, cm.project_company_id AS companyId, cm.project_company_name AS companyName,")
                .line(" e.status AS entryStatus, e.project_code AS projectCode, e.project_name AS projectName, e.age, e.scheme_name AS schemeName,")
                .line("e.tenant_name AS tenantName,e.tenant_name, e.id_code AS idCode, e.roof_type AS roofType, e.tenant_type, cm.if_click_sign, ")
                .line("e.trader_name as traderName,e.trader_name,e.create_trader_name as createTraderName,e.distributor_id,e.create_trader_id, ")
                .line("CONCAT(e.province, e.city, e.area, e.address) AS detailAddress,cm.sign_flow_id,cm.contract_url,e.scheme_name as planName ")
                .line(", e.creator,e.partner_name,e.engineer_name,e.tenant_type AS tenantType ,CONCAT(e.province, e.city, e.area, e.address) AS address ")
                .line(" ,e.create_time ,e.sign_status ,cm.if_click_sign ,e.filing_type ")
                .line("FROM crm_customer_contract_management cm")
                .line("INNER JOIN crm_customer_entry e ON e.id = cm.entry_id")
                .line("WHERE cm.status != '0'");
        appendCondition(builder, map, operator);
        builder.line("ORDER BY cm.invitation_time desc")
                .limit(page.getPage(), page.getLimit());
        return Db.find(builder.build(), builder.params());
    }

    public Record getOneById(Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT cm.id,e.id AS entryId,cm.power_station_code AS powerStationCode,cm.contract_url AS contractUrl,")
                .line(" cm.project_company_name AS companyName, cm.contract_number AS contractNumber,cm.tenant_sign_time AS tenantSignTime,")
                .line("e.tenant_name AS tenantName,")
                .line("CONCAT(e.province, e.city, e.area, e.address) AS detailAddress")
                .line("FROM crm_customer_contract_management cm")
                .line("INNER JOIN crm_customer_entry e ON e.id = cm.entry_id")
                .line("WHERE cm.status != '0' ");
        if (StringUtil.checkParamsValid(map.get("entryId"))) {
            builder.line("AND e.id = ?", map.get("entryId").trim());
        }
        if (StringUtil.checkParamsValid(map.get("id"))) {
            builder.line("and cm.id = ?", map.get("id").trim());
        }
        return Db.findFirst(builder.build(), builder.params());
    }

    public Long countList(Map<String, String> map, Operator operator) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("SELECT count(1)")
                .line("FROM crm_customer_contract_management cm")
                .line("INNER JOIN crm_customer_entry e ON e.id = cm.entry_id")
                .line("WHERE cm.status != '0'");
        appendCondition(builder, map,operator);
        return Db.queryLong(builder.build(), builder.params());
    }

    private void appendCondition(SqlBuilder builder, Map<String, String> map, Operator operator) {
        if(StringUtil.equalsAny(operator.getUserType(), UserConstants.TYPE_TRADER, User.USER_TYPE_ADVISOR)){
            Record record= CrmUtils.getUserTrader(operator.getUserType(),operator.getUserId());
            String traderId =record.getStr("id");
            String type = record.getStr("type");
            if(UserConstants.TYPE_TRADER.equals(operator.getUserType())){  //代理商
                if ("1".equals(type)){  // 1.一级代理商 2.二级代理商
                    builder.line(" and e.distributor_id =?" , traderId );
                }else{  //二级代理商
                    if (UserConstants.TYPE_TRADER.equals(operator.getUserType())) {
                        //代理商只能查看自己的
                        builder.line(" and e.create_trader_id =?" , traderId );
                    }
                }
            }else {
                String dataAuthority=record.getStr("data_authority");
                //一级代理商人员 且拥有查看所有数据的权限  则可以查看到一二级所有数据
                if("1".equals(type) && UserConstants.DATA_AUTHORITY_ALL.equals(dataAuthority)) {
                    builder.line(" and e.distributor_id =?" , traderId );
                } else { //代理商人员
                    builder.line(" and e.create_trader_id =?" , traderId );
                    if(StringUtil.isBlank(dataAuthority) || UserConstants.DATA_AUTHORITY_ONLY.equals(dataAuthority)){
                        builder.line(" and (e.create_by =? ", operator.getUserId());
                        builder.line(" or (e.dispatch_status = '1' and find_in_set(?, e.engineer_id)))", map.get("engineerId"));
                    }
                }
            }
        }
        if (StringUtil.checkParamsValid(map.get("number"))) {
            builder.line("AND cm.contract_number like concat('%', ?, '%')", map.get("number").trim());
        }
        if (StringUtil.checkParamsValid(map.get("customerName"))) {
            builder.line("AND e.tenant_name like concat('%', ?, '%')", map.get("customerName").trim());
        }
        if (StringUtil.checkParamsValid(map.get("powerStationCode"))) {
            builder.line("AND e.power_station_code like concat('%', ?, '%')", map.get("powerStationCode").trim());
        }
        if (StringUtil.checkParamsValid(map.get("mobile"))) {
            builder.line("AND e.mobile = ?", map.get("mobile"));
        }
        /*2024.9.7 增加产品名称和代码的查询*/
        if (StringUtil.checkParamsValid(map.get("projectCode"))) {
            builder.line("and e.project_id=?", map.get("projectCode"));
        }
        if (StringUtil.checkParamsValid(map.get("projectName"))) {
            builder.like("and e.project_name like ?", map.get("projectName"));
        }
        /*end*/
        if (StringUtil.checkParamsValid(map.get("partner"))) {
            builder.line("and e.partner_id =?", map.get("partner"));
        }
        if (StringUtil.checkParamsValid(map.get("idCode"))) {
            builder.line("AND e.id_code like concat('%', ?, '%')", map.get("idCode").trim());
        }
        if (StringUtil.checkParamsValid(map.get("status"))) {
            builder.line("AND cm.status = ?", map.get("status").trim());
        }
        if (StringUtil.checkParamsValid(map.get("statusS"))) {
            builder.inst("AND cm.status in ", map.get("statusS").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("tStatus"))) {
            String status = map.get("tStatus");
            if ("1".equals(status)) {
                builder.line("AND cm.status = '1' ");
            }
            else if ("2".equals(status)) {
                builder.line("AND cm.status in ('2','3') ");
            }
        }
        if (StringUtil.checkParamsValid(map.get("twoTrader"))) {
            builder.line("AND e.create_trader_id = ?", map.get("twoTrader").trim());
        }
        if (StringUtil.checkParamsValid(map.get("traderId"))) {
            builder.line("AND e.distributor_id = ?", map.get("traderId").trim());
        }
        if (StringUtil.checkParamsValid(map.get("signStatus"))) {
            builder.inst("and e.sign_status in ", map.get("signStatus").split(","));
        }
        // 小程序搜索
        if (StringUtil.checkParamsValid(map.get("keyword"))) {
            builder.like("AND (e.project_code LIKE ?",map.get("keyword"));
            builder.like("OR e.power_station_code LIKE ?",map.get("keyword"));
            builder.like("OR e.tenant_name LIKE ?",map.get("keyword"));
            builder.like("OR CONCAT(e.province,e.city,e.area,e.address) LIKE ? ",map.get("keyword"));
            builder.like("OR e.mobile LIKE ?)",map.get("keyword"));
        }
        if (StringUtil.checkParamsValid(map.get("province"))) {
            builder.line("and e.province =?", map.get("province"));
        }
        if (StringUtil.checkParamsValid(map.get("city"))) {
            builder.line("and e.city =?", map.get("city"));
        }
        if (StringUtil.checkParamsValid(map.get("area"))) {
            builder.line("and e.area =?", map.get("area"));
        }
        if (StringUtil.checkParamsValid(map.get("address"))) {
            builder.line("and e.address like concat('%', ?, '%')", map.get("address"));
        }
        long  checkRo= userDao.isDefaultPlatRole(operator.getUserId());
        if (checkRo>0) {
            List<Record> employeeRole = siteEmployeeService.findEmployeeByUserId(operator.getUserId());
            List<String> provinceList = appendColumns(employeeRole, "provices");
            List<String> cityList = appendColumns(employeeRole, "city");
            List<String> numberList = appendColumns(employeeRole, "project_number");
            List<String> traderList = appendColumns(employeeRole, "trader_id");
            logger.info("appendConditions :  count :{}  ,  employeeRole :{}  ，provinceList:{},cityList:{},numberList:{}",checkRo,employeeRole,provinceList,cityList,numberList);
            if (!provinceList.isEmpty()) {
                builder.inst("and e.province in ", provinceList);
            }
            if (!cityList.isEmpty()) {
                builder.inst("and e.city in ", cityList);
            }
            if (!numberList.isEmpty()) {
                builder.inst("and e.project_id in ", numberList);
            }

            if (!traderList.isEmpty()) {
                builder.inst(" and e.distributor_id in ",traderList);
            }
        }
    }
    private List<String> appendColumns(List<Record> records, String column) {
        List<String> ret = new ArrayList<>();
        for (Record record : records) {
            String value = record.getStr(column);
            if (StrKit.notBlank(value)) {
                ret.addAll(Arrays.asList(value.split(",")));
            }
        }
        return ret;
    }

    public CrmCustomerContractManagement getBySignFlowId(String signFlowId){
        return getByHql(" from  CrmCustomerContractManagement where signFlowId= :p1",new Parameter(signFlowId));
    }

    public CrmCustomerContractManagement getByContractNumber(String contractNumber){
        return getByHql(" from  CrmCustomerContractManagement where contractNumber= :p1 and status<>'0' ",new Parameter(contractNumber));
    }

    public CrmCustomerContractManagement getContractByEntryId(String entryId){
        return getByHql(" from  CrmCustomerContractManagement where entryId= :p1 and status not in ('0','h') ",new Parameter(entryId));
    }

    public void setIfClick(String entryId){
        Db.update("UPDATE `crm_customer_contract_management` SET if_click_sign='1' WHERE entry_id=? ",entryId);
    }

    public CrmCustomerContractManagement getContract(String entryId){
        return getByHql(" from  CrmCustomerContractManagement where entryId= :p1 and status not in ('0') ",new Parameter(entryId));
    }
    public void setStatusByEntryId(String status, String entryId){
        Db.update("UPDATE `crm_customer_contract_management` SET status=? WHERE entry_id=?",status,entryId);
    }

    public void changeHistoryContractStatus(String partnersContractNumber){
        SQLQuery sqlQuery = getSession().createSQLQuery("UPDATE crm_customer_contract_management SET status='0'  WHERE  partners_contract_number=:partnersContractNumber AND status<>'0'");
        sqlQuery.setParameter("partnersContractNumber", partnersContractNumber);
        sqlQuery.executeUpdate();
    }

}
