import {
  staticMachineStatus as getStaticMachineStatus,
  staticMachineFeed,
  downExcel,
} from '@/services/machineConnectivity/api';
import React, { useEffect, useMemo, useState } from 'react';
import { FileExcelOutlined } from '@ant-design/icons';
import { message, Popconfirm } from 'antd';
import moment from 'moment';
import * as XLSX from 'xlsx';
import Crust1 from '../../components/FHD1080P/Crust1';
import Style1 from '../../components/FHD1080P/Style1';
import SettingForm from './components/SettingForm/ReportSetting';
import type { Setting } from './components/SettingForm/ReportSetting';
import styles from './index.less';
import MachineProgramException from './components/MachineProgramException';
import MachineStatus from './components/MachineStatus';
import SingleValuePie from './components/SingleValuePie';
import WorkTime from './components/WorkTime';
import WorkTimeUnproduct from './components/WorkTimeUnproduct';
import { queryRptOee, queryRptEquipmentOee } from '@/services/mgr/api';

const Report: React.FC = () => {
  const [setting, setSetting] = useState<Setting>({
    autoResize: false,
    machineProgramExceptionPageTurning: 20,
    from: moment().subtract({ d: 7 }).hour(8).minute(30).second(0).millisecond(0),
    to: moment().hour(8).minute(30).second(0).millisecond(0),
    currentWorkSite: undefined,
    selectedWorkUnits: [],
  });

  const [settingFormVisible, setSettingFormVisible] = useState(false);
  const [startTime, setStartTime] = useState<moment.Moment>();
  const [endTime, setEndTime] = useState<moment.Moment>();
  const [staticMachineStatus, setStaticMachineStatus] =
    useState<MachineConnectivity.StaticMachineStatus>();
  const [machineProgramExecStatArray, setMachineProgramExecStatArray] = useState<
    MachineConnectivity.MachineProgramExecStat[]
  >([]);
  const [oeeData, SetOeeData] = useState<Api.RptOee[]>([]);
  const [equipmentOee, setEquipmentOee] = useState<Api.RptEquipmentOee[]>([]);
  const [conditionKey, setConditionKey] = useState('');

  const summOEE = useMemo(() => {
    let schdTime = 0; // 排产工时
    let taskReportTime = 0; // 产出工时
    let equipmentReportTime = 0; // 设备产出
    let equipmentTime = 0; // 设备开机时间
    let overdueTime = 0; // overdue工时

    equipmentOee.forEach((item) => {
      schdTime += item.schdTime;
      taskReportTime += item.taskReportTime;
      equipmentReportTime += item.equipmentReportTime;
      equipmentTime += item.equipmentTime;
      overdueTime += item.overdueTime;
    });

    const schdTime_overdueTime = schdTime + overdueTime;

    return {
      oee: equipmentTime
        ? Math.round((equipmentReportTime / equipmentTime) * 1000) / 1000
        : undefined,
      oeeErrorText: equipmentOee.length > 0 ? '数据异常' : '',
      prodRate: schdTime_overdueTime
        ? Math.round((taskReportTime / schdTime_overdueTime) * 1000) / 1000
        : undefined,
      prodRateErrorText: equipmentOee.length > 0 ? '数据异常' : '',
    };
  }, [equipmentOee]);

  useEffect(() => {
    const { selectedWorkUnits, from, to } = setting;
    const refresh = async () => {
      const now = Date.now();

      const st = from;
      const et = to;

      setStartTime(st);
      setEndTime(et);

      const rptOeeParam: Api.RptOeeQueryParams = {
        names: selectedWorkUnits.map((w) => w.name),
        from: st.format('YYYY-MM-DDTHH:mm:ss'),
        to: et.format('YYYY-MM-DDTHH:mm:ss'),
      };

      const paramMachine: MachineConnectivity.MachineParams = {
        machines: selectedWorkUnits.map((w) => w.name),
        startTime: st.format('YYYY-MM-DD HH:mm'),
        endTime: et.format('YYYY-MM-DD HH:mm'),
      };

      const rptOeeResp = await queryRptOee(rptOeeParam);
      const rptEquipmentOeeResp = await queryRptEquipmentOee(rptOeeParam);
      const expArray = await staticMachineFeed(paramMachine);
      const machStatus = await getStaticMachineStatus(paramMachine);

      if (!!!machStatus.feedDuration) {
        let feed = 0;
        expArray.forEach((item) => {
          feed = feed + item.feedDuration;
        });
        machStatus.feedDuration = feed;
      }

      SetOeeData(rptOeeResp.data);
      setEquipmentOee(rptEquipmentOeeResp.data);
      setMachineProgramExecStatArray(expArray);
      setStaticMachineStatus(machStatus);

      setConditionKey(now.toString());
    };
    refresh().finally();
    return () => {};
  }, [setting]);

  const downloadExcel1 = async () => {
    if (!!!startTime) {
      message.info('请选择时间');
      return;
    }
    if (!!!endTime) {
      message.info('请选择时间');
      return;
    }
    if (setting.selectedWorkUnits.length <= 0) {
      message.info('请选择作业单元');
      return;
    }
    const hide = message.loading('正在下载Excel...');
    try {
      const ed = oeeData.map((item) => ({
        machine: item.name,
        oee: item.planTime
          ? ((item.actualTime / item.planTime) * 100).toFixed(1) + '%'
          : '数据异常',
        prodRate: item.scheduledTime
          ? ((item.actualTime / item.scheduledTime) * 100).toFixed(1) + '%'
          : '数据异常',
      }));
      const blob = await downExcel({
        machines: setting.selectedWorkUnits.map((w) => w.name),
        startTime: startTime.format('YYYY-MM-DD HH:mm'),
        endTime: endTime.format('YYYY-MM-DD HH:mm'),
        ed,
      });
      const link = document.createElement('a');
      link.style.display = 'none';
      const url = window.URL.createObjectURL(blob);
      link.href = url;
      link.download = `设备效率报表-初版报表-${moment().format('YYYYMMDDHHmmss')}.xlsx`;
      document.body.appendChild(link);
      const evt = new MouseEvent('click', { bubbles: false, cancelable: false });
      link.dispatchEvent(evt);

      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      console.info('downloaded successful.');
    } catch (error) {
      console.info(`downloaded error.${error}`);
    }
    hide();
  };

  const downloadExcel2 = async () => {
    if (!!!startTime) {
      message.info('请选择时间');
      return;
    }
    if (!!!endTime) {
      message.info('请选择时间');
      return;
    }
    if (setting.selectedWorkUnits.length <= 0) {
      message.info('请选择作业单元');
      return;
    }
    const excelData = equipmentOee.map((item) => ({
      机床编号: item.name,
      机床描述: item.description,
      所属工段: item.workSiteName,
      工作中心: item.workCenterName,
      排产工时: item.schdTime,
      产出工时: item.taskReportTime,
      设备产出: item.equipmentReportTime,
      设备开机时间: item.equipmentTime,
      overdue工时: item.overdueTime,
      实际OEE达成: item.equipmentTime
        ? ((item.equipmentReportTime / item.equipmentTime) * 100).toFixed(1) + '%'
        : '数据异常',
      生产任务完成率:
        item.schdTime + item.overdueTime
          ? ((item.taskReportTime / (item.schdTime + item.overdueTime)) * 100).toFixed(1) + '%'
          : '数据异常',
      当期任务完成率: item.schdTime
        ? ((item.taskReportTime / item.schdTime) * 100).toFixed(1) + '%'
        : '数据异常',
    }));
    const workBook = XLSX.utils.book_new();
    const workSheet = XLSX.utils.json_to_sheet(excelData);
    XLSX.utils.book_append_sheet(workBook, workSheet);
    XLSX.writeFile(workBook, `设备效率报表-二版报表-${moment().format('YYYYMMDDHHmmss')}.xlsx`, {
      bookType: 'xlsx',
    });
  };

  return (
    <>
      <Style1
        headerText="设备效率报表"
        autoResize={setting.autoResize}
        onHeaderClick={() => {
          setSettingFormVisible(true);
        }}
      >
        <div className={styles.main}>
          <div className={styles.title}>
            <div className={styles.title_work_site}>
              <div
                className={
                  setting.currentWorkSite
                    ? styles.title_work_site_legend
                    : styles.title_work_site_legend_hidden
                }
              />
              <div className={styles.title_work_site_text}>{setting.currentWorkSite?.name}</div>
            </div>
            <div className={styles.title_machine_time_rage}>
              <div>
                时间：{startTime?.format('YYYY.M.D HH:mm')} - {endTime?.format('YYYY.M.D HH:mm')}
              </div>
            </div>
            <div className={styles.title_machine_count}>
              <div>设备总数：</div>
              <div>{setting.selectedWorkUnits.length}</div>
            </div>
            <div className={styles.title_excel} title="导出到Excel">
              <Popconfirm
                placement="topRight"
                title="导出到Excel"
                onCancel={downloadExcel1}
                onConfirm={downloadExcel2}
                cancelText="初版报表"
                okText="二版报表"
                icon={<FileExcelOutlined />}
                overlayStyle={{
                  width: 200,
                }}
                okButtonProps={{
                  type: 'primary',
                }}
                cancelButtonProps={{
                  type: 'primary',
                }}
              >
                <FileExcelOutlined />
              </Popconfirm>
            </div>
          </div>
          <div className={styles.content}>
            <div className={styles.content_col1}>
              <Crust1 className={styles.crust1}>
                <div className={styles.crust1_content}>
                  <MachineProgramException
                    machineProgramExecStatArray={machineProgramExecStatArray}
                    machineProgramExceptionPageTurning={setting.machineProgramExceptionPageTurning}
                    conditionKey={conditionKey}
                  />
                </div>
              </Crust1>
            </div>
            <div className={styles.content_col2}>
              <div className={styles.content_col2_row1}>
                <div className={styles.content_col2_row1_col1}>
                  <Crust1 className={styles.crust1}>
                    <div className={styles.crust1_content}>
                      <SingleValuePie
                        value={summOEE.oee}
                        errorText={summOEE.oeeErrorText}
                        header="设备OEE"
                        conditionKey={conditionKey}
                      />
                    </div>
                  </Crust1>
                </div>
                <div className={styles.content_col2_row1_col2}>
                  <Crust1 className={styles.crust1}>
                    <div className={styles.crust1_content}>
                      <SingleValuePie
                        value={summOEE.prodRate}
                        errorText={summOEE.prodRateErrorText}
                        header="生产完成率"
                        conditionKey={conditionKey}
                      />
                    </div>
                  </Crust1>
                </div>
                <div className={styles.content_col2_row1_col3}>
                  <Crust1 className={`${styles.crust1}`}>
                    <div
                      className={`${styles.crust1_content} ${styles.content_col2_row1_col3_content}`}
                    >
                      <div className={styles.content_col2_row1_col3_col1}>
                        <WorkTime conditionKey={conditionKey} />
                      </div>
                      <div className={styles.content_col2_row1_col3_col2} />
                      <div className={styles.content_col2_row1_col3_col3}>
                        <WorkTimeUnproduct conditionKey={conditionKey} />
                      </div>
                    </div>
                  </Crust1>
                </div>
              </div>
              <div className={styles.content_col2_row2}>
                <Crust1 className={styles.crust1}>
                  <div className={styles.crust1_content}>
                    <MachineStatus
                      staticMachineStatus={staticMachineStatus}
                      conditionKey={conditionKey}
                    />
                  </div>
                </Crust1>
              </div>
            </div>
          </div>
        </div>
      </Style1>
      <SettingForm
        values={{ ...setting }}
        visible={settingFormVisible}
        onVisibleChange={setSettingFormVisible}
        onSubmitting={async (settingParam) => {
          setSetting({ ...settingParam });
        }}
      />
    </>
  );
};

export default Report;
