package com.sifang.modules.monitor.dao;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.monitor.entity.MonitorCollectData;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import org.springframework.stereotype.Repository;

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

@Repository
public class MonitorCollectDataDao extends BaseDao<MonitorCollectData> {

    /**
     * 获取电站最早发电日期
     */
    public Date findFirstGenerate(List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT ms.stat_date");
        sql.line("FROM crm_monitor_inverter_stat s");
        sql.line("LEFT JOIN crm_monitor_entry_month_stat ms ON ms.station_id = s.station_id");
        sql.inst("WHERE s.sn IN ", snList);
        sql.line(" and ms.energy > 0 ");
        sql.line("ORDER BY ms.stat_date limit 1");
        return Db.queryDate(sql.build(), sql.params());
    }

    /**
     * 统计一段时间内电站发电量(按日统计)
     */
    public List<Record> findDataInThreeDays(List<String> snList, String startDate, String endDate) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT DATE_FORMAT(ms.stat_date,'%Y-%m-%d') AS statDate,ms.energy");
        sql.line("FROM crm_monitor_inverter_stat s");
        sql.line("LEFT JOIN crm_monitor_entry_month_stat ms ON ms.station_id = s.station_id");
        sql.inst("WHERE s.sn IN ", snList);
        sql.line("AND ms.stat_date >= ?", startDate);
        sql.line("AND ms.stat_date <= ?", endDate);
        return Db.find(sql.build(), sql.params());
    }

    /**
     * 查询电站的逆变器sn码
     */
    public List<String> findNbqSnByEntryId(String entryId) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT p.nbq_sn");
        sql.line("FROM crm_customer_entry e");
        sql.line("INNER JOIN crm_plan_material_entry p");
        sql.line("ON p.entry_id = e.id AND p.status='0' AND p.nbq_sn IS NOT NULL AND p.nbq_sn != ''");
        sql.line("WHERE e.id = ?", entryId);
        return Db.query(sql.build(), sql.params());
    }

    public Record overviewStaticData(String entryId) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT s.power AS currentGL,s.etd AS currentEtd,s.eta AS totalEto,s.capacity as ZjGL");
        sql.line("FROM crm_customer_entry as e");
        sql.line("inner JOIN crm_plan_material_entry p  ON p.`entry_id`=e.`id`  AND p.`status`='0' and p.type='逆变器'");
        sql.line("inner join crm_monitor_inverter_stat as invs on invs.sn=p.barcode");
        sql.line("inner join crm_monitor_entry_stat as s on s.station_id=invs.station_id");
        sql.line("where e.id = ? group by e.id", entryId);
        return Db.findFirst(sql.build(), sql.params());
    }

    /**
     * 告警数据
     */
    public Record stationAlarm(List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT COUNT(al.id) AS totalCount,");
        sql.line("COUNT(CASE WHEN al.status IN('3','4') THEN 1 END) AS alarmDeal,");
        sql.line("COUNT(CASE WHEN al.status='2' THEN 1 END) AS alarmUnDeal");
        sql.line("FROM crm_monitor_alarm al");
        sql.line("WHERE al.status IN('2','3','4') AND al.type='2'");
        sql.inst("AND al.sn IN ", snList);
        return Db.findFirst(sql.build(), sql.params());
    }

    /**
     * 统计工单数量
     */
    public Record getOrderDisposeData(List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT COUNT(1) AS total,COUNT(CASE WHEN o.status IN ('5','6','7') THEN 1 END) AS processed");
        sql.line("FROM crm_order o");
        sql.inst("WHERE o.appliance_barcode in ", snList);
        return Db.findFirst(sql.build(), sql.params());
    }

    /**
     * 按日统计
     */
    public Record overviewHourStatic(String time, List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT ds.*");
        sql.line("FROM crm_monitor_entry_daily_stat ds");
        sql.line("INNER JOIN crm_monitor_inverter_stat s");
        sql.inst("ON s.station_id = ds.station_id AND s.sn IN ", snList);
        sql.line("WHERE ds.stat_date = ?", time);
        return Db.findFirst(sql.build(), sql.params());
    }

    /**
     * 按月统计
     */
    public List<Record> overviewMonthStatic(String time, List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT DATE_FORMAT(ms.stat_date,'%d') AS xAxis,ms.energy");
        sql.line("FROM crm_monitor_entry_month_stat ms");
        sql.line("INNER JOIN crm_monitor_inverter_stat s");
        sql.inst("ON s.station_id = ms.station_id AND s.sn IN ", snList);
        sql.line("WHERE DATE_FORMAT(ms.stat_date,'%Y-%m') = ?", time);
        sql.line("ORDER BY ms.stat_date");
        return Db.find(sql.build(), sql.params());
    }

    /**
     * 按年统计
     */
    public List<Record> overviewYearStatic(String time, List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT ys.month,ys.energy");
        sql.line("FROM crm_monitor_entry_year_stat ys");
        sql.line("INNER JOIN crm_monitor_inverter_stat s");
        sql.inst("ON s.station_id = ys.station_id AND s.sn IN ", snList);
        sql.line("WHERE ys.year = ?", time);
        sql.line("ORDER BY ys.month");
        List<Record> list = Db.find(sql.build(), sql.params());
        for (Record r : list) {
            for (int i = 1; i <= 12; i++) {
                String str = i + "";
                if (i < 10) {
                    str = "0" + i;
                }
                if (i == r.getInt("month")) {
                    r.set("xAxis", str);
                    break;
                }
            }
        }
        return list;
    }

    public List<Record> currentYearGeneration(String year, List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT SUM(eto) AS eto, xAxis FROM(");
        sql.line("SELECT MAX(eto) AS eto,");
        sql.line("DATE_FORMAT(ANY_VALUE(re.tim),'%Y-%m') createTime,DATE_FORMAT(ANY_VALUE(re.tim),'%m')AS xAxis");
        sql.line("FROM `crm_monitor_collect_data` re");
        sql.line("WHERE  DATE_FORMAT(tim,'%Y') = ?", year);
        sql.inst("and re.sn in ", snList);
        sql.line("AND re.tim>(SELECT LAST_DAY( MIN(tim)) FROM `crm_monitor_collect_data` WHERE");
        sql.inst("sn IN ", snList);
        sql.line(") GROUP BY createTime");
        sql.line("ORDER BY createTime");
        sql.line(") AS a");
        sql.line("GROUP BY createTime");
        return Db.query(sql.build(), sql.params());
    }

    public List<Record> currentMonthGeneration(String month, List<String> snList) {
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT SUM(eto) AS eto, xAxis FROM(");
        sql.line("SELECT MAX(eto) AS eto,");
        sql.line("DATE_FORMAT(ANY_VALUE(re.tim),'%Y-%m') createTime,DATE_FORMAT(ANY_VALUE(re.tim),'%m')AS xAxis");
        sql.line("FROM `crm_monitor_collect_data` re");
        sql.line("WHERE DATE_FORMAT(tim,'%Y-%m') = ?", month);
        sql.inst("and re.sn in ", snList);
        sql.line("AND re.tim > (SELECT LAST_DAY( MIN(tim)) FROM `crm_monitor_collect_data` WHERE");
        sql.inst("sn IN ", snList);
        sql.line(") GROUP BY createTime");
        sql.line("ORDER BY createTime");
        sql.line(") AS a");
        sql.line("GROUP BY createTime");
        return Db.query(sql.build(), sql.params());
    }

    public Integer getTheoryEfficiency(String type, String province, String area) {
        return Db.queryInt("SELECT e.first_hour FROM crm_monitor_theory_efficiency e WHERE e.plan_type = ? AND e.province = ? AND e.area = ?", type, province, area);
    }

    public List<Record> selectEquipmentInfoList(LayuiPage<Record> page, Map<String, String> map){
        SqlBuilder sql = new SqlBuilder();
        sql.line("select a.*,csm.material_brand as materialBrand from (");
        sql.line("SELECT e.id AS entryId, p.name AS deviceName,p.nbq_sn AS SNCode,1 AS deviceType,p.spec AS deviceModel,1 AS status, p.nbq_sn AS sort, p.material_id");
        sql.line("FROM `crm_customer_entry` e");
        sql.line("INNER JOIN crm_plan_material_entry p  ON p.`entry_id`= e.`id` AND p.status='0' AND p.nbq_sn != ''");
        sql.line("WHERE e.id = ? ", map.get("id"));
        sql.line("UNION ALL");
        sql.line("SELECT e.id AS entryId, CONCAT(p.nbq_sn,'采集器') AS deviceName,p.sn AS SNCode,2 AS deviceType,p.spec AS deviceModel,1 AS STATUS, p.nbq_sn AS sort, p.material_id");
        sql.line("FROM crm_customer_entry e");
        sql.line("LEFT JOIN crm_plan_material_entry p  ON p.`entry_id`=e.`id` AND p.status='0' AND p.sn != ''");
        sql.line("WHERE e.id = ? ", map.get("id"));
        //getConditionMap(map,builder);
        sql.line(" ORDER BY sort,deviceType ");
        sql.line(")a" );
        sql.line("left join crm_supply_material csm ON a.material_id = csm.id");
        sql.line("WHERE 1 = 1 " );
        sql.line(getConditionMap(map));
        if(page != null){
            sql.limit(page.getPage(), page.getLimit());
        }
        return Db.find(sql.build(), sql.params());
    }

    public Long countEquipmentInfo(Map<String, String> map){
        SqlBuilder sql = new SqlBuilder();
        sql.line("SELECT COUNT(1) FROM");
        sql.line("(SELECT e.id AS entryId, p.name AS deviceName,p.nbq_sn AS SNCode,1 AS deviceType");
        sql.line("FROM `crm_customer_entry` e");
        sql.line("INNER JOIN crm_plan_material_entry p  ON p.`entry_id`= e.`id` AND p.status='0' AND p.nbq_sn != ''");
        sql.line("WHERE e.id = ? ", map.get("id"));
        sql.line("UNION ALL");
        sql.line("SELECT e.id AS entryId, p.name AS deviceName,p.sn AS SNCode,2 AS deviceType");
        sql.line("FROM crm_customer_entry e");
        sql.line("LEFT JOIN crm_plan_material_entry p  ON p.`entry_id`=e.`id` AND p.status='0' AND p.sn != ''");
        sql.line("WHERE e.id = ? ", map.get("id"));
        sql.line(") AS a");
        sql.line("WHERE 1 = 1 " );
        sql.line(getConditionMap(map));
        //getConditionMap(map,builder);
        return Db.queryLong(sql.build(), sql.params());
    }

    public String getConditionMap(Map<String, String> map) {
        StringBuilder sf = new StringBuilder();
        if (StringUtil.checkParamsValid(map.get("deviceName"))) {
            sf.append(" and a.deviceName LIKE '%" + map.get("deviceName") + "%'");
        }
        if (StringUtil.checkParamsValid(map.get("SNCode"))) {
            sf.append(" and a.SNCode LIKE '%" + map.get("SNCode") + "%'");
        }
        if (StringUtil.checkParamsValid(map.get("deviceType"))) {
            sf.append(" and a.deviceType =" + map.get("deviceType"));
        }
        return sf.toString();
    }
}
