package com.sifang.modules.supply.order.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.site.siteInfo.dao.SiteEmployeeDao;
import com.sifang.modules.site.siteInfo.service.SiteEmployeeService;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialApply;
import com.sifang.modules.sys.common.UserUtils;
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 com.sifang.modules.sys.util.SqlUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
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;

/**
 * @author hongzq
 */
@Repository
public class MaterialApplyDao extends BaseDao<CrmSupplyMaterialApply> {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    UserDao userDao;
    @Autowired
    SiteEmployeeService siteEmployeeService;

    public int deleteOrderByIds(List<String> ids) {
        String hql = "update CrmSupplyMaterialApply set status='0' where id in (:ids)";
        Query query = getSession().createQuery(hql);
        query.setParameterList("ids", ids);
        return query.executeUpdate();
    }

    public List<CrmSupplyMaterialApply> findOrderByIds(List<String> ids) {
        String hql = "from CrmSupplyMaterialApply where status <> '0' and id in (:ids)";
        Query query = getSession().createQuery(hql);
        query.setParameterList("ids", ids);
        return (List<CrmSupplyMaterialApply>) query.list();
    }

    public List<Record> applyOrderList(LayuiPage<Record> page, Map<String, String> map, Operator operator) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select a.id, a.number, a.project_id, a.project_code, a.status, a.creator, w.name as inWarehouseName,a.province,a.city,a.area,a.address, a.relate_no, a.remark ")
                .line(", a.create_time, a.order_time, a.in_warehouse_id, t.name as traderName, a.order_to_name, a.fail_reason")
                .line(", a.material_type_amount, a.total_apply_amount, a.material_type_amount, a.total_apply_amount, a.audit_time")
                .line(", IFNULL(a.mobile,w.mobile) as mobile, concat(w.province, w.city, w.area, w.address) as w_address, IFNULL(a.person_in_charge,w.person_in_charge) as person_in_charge")
                .line("from crm_supply_material_apply a")
                .line("left join crm_supply_warehouse w on a.in_warehouse_id=w.id")
                .line("left join crm_trader t on a.trader_id=t.id")
                .line("where a.status <> '0'");
        appendApplyOrderCondition(builder, map, operator);
        builder.line("order by a.create_time desc");
        if (page != null) {
            builder.limit(page.getPage(), page.getLimit());
        }
        return Db.find(builder.build(), builder.params());
    }

    public Long countApplyOrderList(Map<String, String> map, Operator operator) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select count(1) ")
                .line("from crm_supply_material_apply a")
                .line("left join crm_trader t on a.trader_id=t.id")
                .line("where a.status <> '0'");
        appendApplyOrderCondition(builder, map, operator);
        return Db.queryLong(builder.build(), builder.params());
    }

    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;
    }

    private void appendApplyOrderCondition(SqlBuilder builder, Map<String, String> map, Operator operator) {
        if (UserConstants.TYPE_PLAT_EMP.equals(operator.getUserType())) {
            //查找员工数据权限
            List<Record> employeeRole = siteEmployeeService.findEmployeeByUserId(operator.getUserId());
            List<String> traderList = appendColumns(employeeRole, "trader_id");
            List<String> materialList = appendColumns(employeeRole, "material_id");
            logger.info("appendConditions :  traderList :{}  ,  materialList :{}", traderList, materialList);
            if (!traderList.isEmpty()) {
                builder.inst("and a.trader_id in ", traderList);
            }
            if (!materialList.isEmpty()) {
                builder.line("and exists (select 1 from crm_supply_material_apply_detail d where d.apply_id=a.id and d.material_id in" + "(" + SqlUtils.inParam(materialList) + "))");
            }
        } else if (StringUtils.endsWithAny(operator.getUserType(), "6", "7")) {
            String traderId = CrmUtils.getCurrentTraderId(operator.getUserId());
            builder.line("and a.trader_id = ?", traderId);
        }
        if (StringUtil.checkParamsValid(map.get("traderId"))) {
            builder.line("and a.trader_id = ?", map.get("traderId"));
        }
        if (StringUtil.checkParamsValid(map.get("number"))) {
            builder.like("and a.number like ?", map.get("number").trim());
        }
        if (StringUtil.checkParamsValid(map.get("relateNo"))) {
            builder.like("and a.relate_no like ?", map.get("relateNo").trim());
        }
        if (StringUtil.checkParamsValid(map.get("status"))) {
            builder.inst("and a.status IN ", map.get("status").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("waitAuditQuery"))) {
            builder.line("and a.status IN ('1', '2', '3')");
        }
        if (StringUtil.checkParamsValid(map.get("creator"))) {
            builder.like("and a.creator like ?", map.get("creator").trim());
        }
        if (StringUtil.checkParamsValid(map.get("traderName"))) {
            builder.like("and t.name like ?", map.get("traderName").trim());
        }
        if (StringUtil.checkParamsValid(map.get("projectCode"))) {
            builder.like("and a.project_code like ?", map.get("projectCode").trim());
        }
        if (StringUtil.checkParamsValid(map.get("inWarehouseId"))) {
            builder.inst("and a.in_warehouse_id in ", map.get("inWarehouseId").split(","));
        }
        if (StringUtil.checkParamsValid(map.get("remark"))) {
            builder.like("and a.remark like ?", map.get("remark").trim());
        }
        if (StringUtil.checkParamsValid(map.get("createTimeMin"))) {
            builder.line("and a.create_time >= ?", map.get("createTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("createTimeMax"))) {
            builder.line("and a.create_time <= ?", map.get("createTimeMax"));
        }
        if (StringUtil.checkParamsValid(map.get("orderTimeMin"))) {
            builder.line("and a.order_time >= ?", map.get("orderTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("orderTimeMax"))) {
            builder.line("and a.order_time <= ?", map.get("orderTimeMax"));
        }
        if (StringUtil.checkParamsValid(map.get("auditTimeMin"))) {
            builder.line("and a.audit_time >= ?", map.get("auditTimeMin"));
        }
        if (StringUtil.checkParamsValid(map.get("auditTimeMax"))) {
            builder.line("and a.audit_time <= ?", map.get("auditTimeMax"));
        }
        if (StringUtil.checkParamsValid(map.get("applyId"))) {
            builder.line("and a.id = ?", map.get("applyId"));
        }
        if (StringUtil.checkParamsValid(map.get("orderToName"))) {
            builder.like("and a.order_to_name like ?", map.get("orderToName").trim());
        }
    }

    public CrmSupplyMaterialApply findByNumber(String number) {
        return getByHql("from CrmSupplyMaterialApply where number=:p1", new Parameter(number));
    }

    public Record statisticOrderForSupplyChain() {
        return Db.findFirst("select count(*) as dsp from crm_supply_material_apply where status in ('1', '2', '3')");
    }

    public Record statisticOrderForTraderDsp() {
        return Db.findFirst("select count(*) from crm_supply_material_apply where status in('1', '2', '3') and trader_id = ?", CrmUtils.getCurrentTraderId(UserUtils.getUser()));
    }
    public Record statisticOrderForTraderDfh() {
        return Db.findFirst("select count(*) as dfh from crm_supply_material_apply where status = '9' and trader_id = ?", CrmUtils.getCurrentTraderId(UserUtils.getUser()));
    }
}
