import TabsContent from '@/components/TabsContent';
import {
  queryBackwash,
  queryBackwashList,
  queryDesignNob,
  queryDesignNobList,
  queryDesignWash,
  queryDesignWashList,
  queryDrug,
  queryDrugList,
  queryMembrane,
  queryMembraneConditions,
  queryMembraneList,
  queryProjectConfig,
  queryPump,
  queryPumpList,
} from '@/services/SmartOps';
import { AreaChartOutlined } from '@ant-design/icons';
import { useRequest } from '@umijs/max';
import { DatePicker, Modal, Select, Spin } from 'antd';
import dayjs from 'dayjs';
import * as echarts from 'echarts';
import { useEffect, useRef, useState } from 'react';
import styles from './SimulateDetail.less';

const { RangePicker } = DatePicker;

const TYPE = {
  td_uf: {
    name: '超滤膜',
    device: (params) => queryMembraneList({ ...params, type: 'uf' }),
    chart: (params) => queryMembrane({ ...params, type: 'uf' }),
  },
  td_mf: {
    name: '微滤膜',
    device: (params) => queryMembraneList({ ...params, type: 'mf' }),
    chart: (params) => queryMembrane({ ...params, type: 'mf' }),
  },
  td_nf: {
    name: '纳滤膜',
    device: (params) => queryMembraneList({ ...params, type: 'nf' }),
    chart: (params) => queryMembrane({ ...params, type: 'nf' }),
  },
  td_ro: {
    name: '反渗透膜',
    device: (params) => queryMembraneList({ ...params, type: 'ro' }),
    chart: (params) => queryMembrane({ ...params, type: 'ro' }),
  },
  tdr_pac: {
    name: '絮凝剂投加',
    device: (params) => queryDrugList({ ...params, type: 'pac' }),
    chart: (params) => queryDrug({ ...params, type: 'pac' }),
  },
  tdr_hci: {
    name: 'HCI投加',
    device: (params) => queryDrugList({ ...params, type: 'hci' }),
    chart: (params) => queryDrug({ ...params, type: 'hci' }),
  },
  tdr_nob: {
    name: '非氧化杀菌剂投加',
    device: (params) => queryDrugList({ ...params, type: 'nob' }),
    chart: (params) => queryDrug({ ...params, type: 'nob' }),
  },
  tt_backwash: {
    name: '反冲洗记录',
    device: queryBackwashList,
    chart: queryBackwash,
  },
  tt_wash: {
    name: '大水量冲洗记录',
    device: queryDesignWashList,
    chart: queryDesignWash,
  },
  tt_nob: {
    name: '非氧化杀菌记录',
    device: queryDesignNobList,
    chart: queryDesignNob,
  },
  td_pump_nf: {
    name: '纳滤水泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_nf' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_nf' }),
  },
  td_pump_uf: {
    name: '超滤水泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_uf' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_uf' }),
  },
  td_pump_ro: {
    // td_pump: {
    name: '反渗透水泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_ro' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_ro' }),
  },
  td_pump_mf: {
    name: '微滤水泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_mf' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_mf' }),
  },
  td_pump_nf_drug: {
    name: '加药泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_nf_drug' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_nf_drug' }),
  },
  td_pump_uf_drug: {
    name: '加药泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_uf_drug' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_uf_drug' }),
  },
  td_pump_ro_drug: {
    // td_pump: {
    name: '加药泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_ro_drug' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_ro_drug' }),
  },
  td_pump_mf_drug: {
    name: '加药泵',
    device: (params) => queryPumpList({ ...params, stage: 'td_pump_mf_drug' }),
    chart: (params) => queryPump({ ...params, stage: 'td_pump_mf_drug' }),
  },
};
const SimulateDetail = (props) => {
  const { projectId } = props;
  const [active, setActive] = useState();
  const [current, setCurrent] = useState();

  const { data } = useRequest(queryProjectConfig, {
    defaultParams: [projectId],
    onSuccess(data) {
      setActive(data[0]);
    },
  });

  return (
    <div style={{ marginTop: 10 }}>
      {data && (
        <TabsContent
          center={false}
          small
          defaultActiveKey={data[0]}
          items={data.map((item) => ({
            label: TYPE[item]?.name,
            key: item,
            children: <div></div>,
          }))}
          onChange={(value) => {
            setActive(value);
            setCurrent(null);
          }}
        ></TabsContent>
      )}

      <div className={`${styles.box} card-box`}>
        <ChartContent
          active={active}
          projectId={projectId}
          current={current}
          setCurrent={setCurrent}
        />
      </div>
    </div>
  );
};

const DateTab = [
  {
    value: 'day',
    label: '今日',
  },
  {
    value: 'week',
    label: '本周',
  },
  {
    value: 'month',
    label: '本月',
  },
];
const ChartContent = (props) => {
  const { current, projectId, active, setCurrent } = props;
  const [visible, setVisible] = useState(false);
  const [params, setParams] = useState(null);
  const [dateActive, setDateActive] = useState('day');
  const [time, setTime] = useState([dayjs().startOf('day'), dayjs()]);
  const timerRef = useRef({
    s_time: time[0].format('YYYY-MM-DD HH:mm:ss'),
    e_time: time[1].format('YYYY-MM-DD HH:mm:ss'),
  });
  const domRef = useRef(null);
  const chartRef = useRef(null);

  const { data, run, loading } = useRequest(
    () => {
      let params = {
        device_code: current.device_code,
        page: 1,
        page_size: 9999,
        project_id: projectId,
        ...timerRef.current,
      };
      setParams(params);
      return TYPE[active].chart(params);
    },
    {
      manual: true,
      onSuccess(data) {
        chartRef.current.clear();
        let options = getOption(data.list, active);
        chartRef.current.setOption(options, true);
        chartRef.current.resize();
      },
    },
  );

  const searchTime = (type) => {
    setDateActive(type);
    let time = [dayjs().startOf(type), dayjs()];
    onSearch?.(time);
  };

  const onSearch = (time) => {
    if (time && time.length == 2) {
      let s_time, e_time;
      s_time = time[0].format('YYYY-MM-DD HH:mm:ss');
      e_time = time[1].format('YYYY-MM-DD HH:mm:ss');

      timerRef.current = { s_time, e_time };
      setTime(time);
      run();
    }
  };

  useEffect(() => {
    chartRef.current = echarts.init(domRef.current);

    return () => {
      chartRef.current.dispose();
    };
  }, []);

  useEffect(() => {
    if (current?.device_code && active) {
      run();
    } else {
      chartRef.current.clear();
    }
  }, [current, active]);

  return (
    <div className={styles.chartBox}>
      <div className={styles.chartBoxTop}>
        <DeviceList
          active={active}
          projectId={projectId}
          current={current}
          onClick={setCurrent}
        />

        <div style={{ display: 'flex' }}>
          <div className={styles.dateTabs}>
            {DateTab.map((item) => (
              <div
                key={item.value}
                className={`${styles.dateTabsItem} ${
                  item.value == dateActive ? styles.active : ''
                }`}
                onClick={() => searchTime(item.value)}
              >
                {item.label}
              </div>
            ))}
          </div>
          {active == 1 && (
            <AreaChartOutlined
              style={{ float: 'right', lineHeight: '56px', marginRight: 20 }}
              onClick={() => setVisible(true)}
            />
          )}
        </div>
      </div>
      <Spin spinning={loading}>
        <div ref={domRef} style={{ height: '35vh' }} />
      </Spin>
      <Optimization data={data?.list?.[0]} />
      <MembraneModal
        visible={visible}
        onCancel={() => setVisible(false)}
        params={params}
      />
    </div>
  );
};

const DeviceList = (props) => {
  const { current, onClick, projectId, active } = props;

  const { data, loading, run } = useRequest(
    () => {
      let params = {
        page: 1,
        page_size: 99999,
        project_id: projectId,
      };
      return TYPE[active]?.device(params);
    },
    {
      manual: true,
      onSuccess(data) {
        if (data.list?.[0]) {
          onClick(data.list[0]);
        } else {
          onClick(null);
        }
      },
    },
  );

  const handleChange = (value) => {
    let current = data.list.find((item) => item.device_code == value);
    onClick(current);
  };

  useEffect(() => {
    if (active) run();
  }, [active]);

  return (
    <Select
      style={{ width: 200 }}
      onChange={handleChange}
      value={current?.device_code}
    >
      {data?.list.map((item) => (
        <Select.Option key={item.device_code}>{item.device_code}</Select.Option>
      ))}
    </Select>
  );
};
function getOption(data = [], active) {
  let formatter,
    yAxisName = '',
    y2AxisName = '',
    series = [],
    xAxis = [];
  var data1 = [],
    data2 = [],
    data3 = [],
    data4 = [];
  switch (active) {
    case 'tt_backwash':
      yAxisName = '清洗周期/Min';
      formatter = (params) => {
        let item = data[params[0].dataIndex];
        let content = '';
        if (item.bw_type == 1) {
          // PEB
          content += 'PEB 反洗开始时间：' + item.peb_st;
          content += '<br />PEB 反洗结束时间：' + item.peb_et;
        } else {
          // CEB
          content += 'CEB 反洗开始时间：' + item.ceb_st;
          content += '<br />CEB 反洗结束时间：' + item.ceb_et;
          content += '<br />CEB 清洗剂浓度' + item.ceb_ppm;
        }
        return content;
      };
      data?.forEach((item) => {
        if (item.bw_type == 1) {
          // 实际冲洗
          data1.push(Math.ceil(item.peb_interval / 60));
          // TODO:冲洗
          data2.push(Math.ceil(item.peb_interval / 60));
          data3.push(null);
          data4.push(null);
          xAxis.push(dayjs(item.peb_st).format('YYYY-MM-DD HH:mm:ss'));
        } else {
          data1.push(null);
          data2.push(null);
          data3.push(Math.ceil(item.peb_interval / 60));
          // TODO:模拟冲洗
          data4.push(Math.ceil(item.peb_interval / 60));
          xAxis.push(dayjs(item.ceb_st).format('YYYY-MM-DD HH:mm:ss'));
        }
      });
      series = [
        {
          name: '物理实际冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data1,
        },
        {
          name: '物理模拟冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data2,
        },
        {
          name: '化学实际冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data3,
        },
        {
          name: '化学模拟冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data4,
        },
      ];
      break;
    case 'tt_wash':
      yAxisName = '清洗周期/Min';
      formatter = (params) => {
        let item = data[params[0].dataIndex];
        let content = '';
        content += '反洗开始时间：' + item.st;
        content += '<br />反洗结束时间：' + item.et;
        return content;
      };
      data?.forEach((item) => {
        // 实际冲洗
        data1.push(Math.ceil(item.interval / 60));
        // TODO:模拟冲洗
        data2.push(Math.ceil(item.interval / 60));
        xAxis.push(dayjs(item.st).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '实际冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data1,
        },
        {
          name: '模拟冲洗',
          type: 'bar',
          barMaxWidth: '20px',
          data: data2,
        },
      ];
      break;
    case 'tt_nob':
      yAxisName = '杀菌周期/Min';
      formatter = (params) => {
        let item = data[params[0].dataIndex];
        let content = '';
        content += '杀菌开始时间：' + (item.st || '-');
        content += '<br />杀菌结束时间：' + (item.et || '-');
        return content;
      };
      var data1 = [],
        data2 = [];
      data?.forEach((item) => {
        // 实际冲洗
        data1.push(Math.ceil(item.interval / 60));
        // TODO:模拟冲洗
        data2.push(Math.ceil(item.interval / 60));
        xAxis.push(dayjs(item.st).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '实际',
          type: 'bar',
          barMaxWidth: '20px',
          data: data1,
        },
        {
          name: '模拟',
          type: 'bar',
          barMaxWidth: '20px',
          data: data2,
        },
      ];
      break;
    case 'tdr_hci':
    case 'tdr_nob':
    case 'tdr_pac':
      yAxisName = '投加量';
      data?.forEach((item) => {
        // 实际冲洗
        data1.push(Math.ceil(item.fr / 60));
        // TODO:模拟冲洗
        data2.push(Math.ceil(item.fcoa / 60));
        xAxis.push(dayjs(item.c_time).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '实际物理投加量',
          type: 'bar',
          barMaxWidth: '20px',
          data: data1,
        },
        {
          name: '理论物理投加量',
          type: 'bar',
          barMaxWidth: '20px',
          data: data2,
        },
      ];
      break;

    case 'td_uf':
    case 'td_mf':
    case 'td_nf':
      yAxisName = '渗透率';
      data?.forEach((item) => {
        // 实际跨膜压差
        data1.push(item.std_tmp);
        // 模拟跨膜压差
        data2.push(item.std_permeability);
        xAxis.push(dayjs(item.c_time).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '标准跨膜压差',
          type: 'line',
          data: data1,
          showSymbol: false,
        },
        {
          name: '标准渗透率',
          type: 'line',
          data: data2,
          showSymbol: false,
        },
      ];
      break;
    case 'td_ro':
      yAxisName = '跨膜压差';
      data?.forEach((item) => {
        // 实际跨膜压差
        data1.push(item.extend['1st_Stage_DP']);
        data2.push(item.extend['2nd_Stage_DP']);
        // 模拟跨膜压差
        data3.push(item.stabilize_extend['1st_Stage_DP']);
        data4.push(item.stabilize_extend['2nd_Stage_DP']);
        xAxis.push(dayjs(item.c_time).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '实际一段跨膜压差',
          type: 'line',
          data: data1,
          showSymbol: false,
        },
        {
          name: '实际二段跨膜压差',
          type: 'line',
          data: data2,
          showSymbol: false,
        },
        {
          name: '模拟一段跨膜压差',
          type: 'line',
          data: data3,
          showSymbol: false,
        },
        {
          name: '模拟二段跨膜压差',
          type: 'line',
          data: data4,
          showSymbol: false,
        },
      ];
      break;
    case 'td_pump_nf':
    case 'td_pump_uf':
    case 'td_pump_ro':
    // case 'td_pump':
    case 'td_pump_mf':
    case 'td_pump_nf_drug':
    case 'td_pump_mf_drug':
    case 'td_pump_mf_drug':
    case 'td_pump_mf_drug':
      yAxisName = '频率 Hz';
      y2AxisName = '电流 A';
      data?.forEach((item) => {
        // 实际跨膜压差
        data1.push(item.frequency);
        data2.push(item.current);
        xAxis.push(dayjs(item.c_time).format('YYYY-MM-DD HH:mm:ss'));
      });
      series = [
        {
          name: '频率',
          type: 'line',
          data: data1,
          showSymbol: false,
        },
        {
          name: '电流',
          type: 'line',
          data: data2,
          yAxisIndex: 1,
          showSymbol: false,
        },
      ];
      break;
  }

  const option = {
    color: ['#FFC800', '#30EDFD', '#4096ff', '#ff4d4f', '#ffa940'],
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      textStyle: {
        fontSize: 24,
      },
      formatter,
    },
    legend: {
      textStyle: {
        // color: '#fff',
        fontSize: 24,
      },
      type: 'scroll',
    },
    grid: {
      top: 80,
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: xAxis,
      nameTextStyle: {
        fontSize: 24,
      },
      axisLabel: {
        fontSize: 24,
      },
    },
    yAxis: {
      name: yAxisName,
      type: 'value',
      boundaryGap: [0, 0.01],
      nameTextStyle: {
        fontSize: 24,
      },
      axisLabel: {
        fontSize: 24,
      },
      splitNumber: 5,
    },
    series,
  };
  if (y2AxisName) {
    let y1 = option.yAxis;
    let y2 = JSON.parse(JSON.stringify(y1));
    y2 = { ...y2, name: y2AxisName };
    option.yAxis = [y1, y2];
  }
  console.log(option);
  return option;
}

const MembraneModal = (props) => {
  const { visible, onCancel, params } = props;
  const domRef = useRef(null);
  const chartRef = useRef(null);

  const { run, loading } = useRequest(queryMembraneConditions, {
    manual: true,
    onSuccess(data) {
      console.log(data);
      let options = getMembraneOption(data.list);
      chartRef.current.setOption(options, true);
    },
  });

  useEffect(() => {
    if (visible) {
      if (!chartRef.current) {
        chartRef.current = echarts.init(document.getElementById('chart'));
        run(params);
      }
    }
  }, [visible]);

  return (
    <Modal
      forceRender
      title="渗透率图表"
      open={visible}
      onCancel={onCancel}
      footer={null}
    >
      <Spin spinning={loading}>
        <div id="chart" style={{ height: '60vh' }} />
      </Spin>
    </Modal>
  );
};
function getMembraneOption(data = []) {
  const option = {
    color: ['#FFC800', '#30EDFD', '#4096ff', '#ff4d4f', '#ffa940'],
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      textStyle: {
        fontSize: 24,
      },
    },
    legend: {
      textStyle: {
        // color: '#fff',
        fontSize: 18,
      },
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: data.map((item) => item.c_time),
      axisLine: {
        lineStyle: {
          // color: '#fff',
        },
      },
      splitLine: {
        lineStyle: {
          // color: '#fff',
        },
      },
      axisLabel: {
        // color: '#fff',
      },
    },
    yAxis: {
      name: '渗透率',
      type: 'value',
      boundaryGap: [0, 0.01],
      axisLine: {
        lineStyle: {
          // color: '#fff',
        },
      },
      splitLine: {
        lineStyle: {
          // color: '#fff',
        },
      },
      axisLabel: {
        // color: '#fff',
      },
    },
    series: [
      {
        type: 'line',
        showSymbol: false,
        areaStyle: {
          opacity: 0.1,
        },
        type: 'line',
        smooth: true,
        data: data.map((v) => v.permeability),
      },
    ],
  };

  return option;
}

const Optimization = ({ data }) => {
  if (!data?.optimization) return '';

  const NAME_MAP = {
    peb_interval: '反冲洗周期调整',
    pac_fr: '絮凝剂投加建议',
    ceb_residue_count: '超滤微滤, 剩余药洗次数',
    ceb_permeability: '超滤微滤, 渗透率低于阈值, 药洗提醒',
    ceb_time_expire: '超滤微滤药洗提醒',
    ro_pressure_1st: 'ro一段运行状况',
    ro_pressure_2nd: 'ro二段运行状况',
    ro_pressure_3th: 'ro三段运行状况',
    ro_nob_interval: 'ro非氧化杀菌调整',
    ro_wash_interval: 'ro冲洗调整',
    ro_residue_count: 'ro化学清洗后,剩余的可清洗次数',
  };

  return (
    <div className={styles.optimization}>
      <div className={styles.title1}>
        {dayjs(data.c_time).format('YYYY-MM-DD HH:mm')}
      </div>
      <div className={styles.title2}>调整内容</div>
      {Object.entries(data.optimization).map(([key, item]) => (
        <div key={key} className={styles.content}>
          【{NAME_MAP[key]}】{item.remark}
        </div>
      ))}
    </div>
  );
};

export default SimulateDetail;
