import { SchemaCollection } from ".."
import { expressLabels, IExpress } from "../renderers/Lion/ExpressPrint/ExpressPrint"
import { Api } from "../types"
import { Shell } from "./shell"
import MSG from '../renderers/Lion/utils/msgsub';
import { message } from "antd";
import { isMobile } from "./helper";
import { getDestoryResult, getModifyResult, windowRFIDTriger } from "./RfidUtil";
import { buildLabelTemplate, setLabelTemplateData } from "./print/util";
import { labelPrint } from "./print";

interface ScanAfterLabelPrint {
  labelData: any[]
  labelTemplate: any
  labelPrinter: string
}

interface FrontPort {
  afterApi: Api
  bodyList: { EPC: string }[]
  actionName: string
  EPC: string
  portId: 'rfid-in-stock' | 'rfid-sold' | 'rfid-scrap' | 'rfid-been-dispatched'
}

interface ScanAfterPort {
  afterApi?: Api
  body: IExpress
}

interface ScanAfterShow {
  showType: 0 | 1 | 2 | 10 | 11 | 12
  showMsg: string
  afterApi?: Api
}

interface ScanAfterVars {
  afterApi: Api
  body: SchemaCollection
  data: object
}


export interface ScanAfterDo {
  cmd: 'STEP_PRINT_LABEL' | 'STEP_PORT' | 'STEP_SHOW' | 'STEP_VARS' | 'STEP_FRONT_PORT'
  body: ScanAfterLabelPrint | ScanAfterPort | ScanAfterShow | ScanAfterVars | FrontPort
}

// rfid keystep功能port enum
enum RFIDPortIdEnum {
  RFIDINSTOCK = 'rfid-in-stock', // 在库
  RFIDSOLD = 'rfid-sold', // 已售
  RFIDSCRAP = 'rfid-scrap', // 废弃
  RFIDBEENDISPATCHED = 'rfid-been-dispatched',  // 调出
  RFIDEPCOVERWRITE = 'rfid-epc-overwrite', // 覆写
  RFIDEPCDESTORY = 'rfid-epc-destory', // 销毁
  ACTRFID = 'actRfid' // 广播触发
}

// 专门处理epc用的
export const epc_front_port = async (element: ScanAfterDo, data: any, env: any) => {
  let error = false
  let errorData = ''
  let payload
  const body = element.body as FrontPort
  const bodyList = body.bodyList // 获取需要设置的请求体
  const portId = body.portId // 获取需要设置的请求体
  // portId对应的状态码
  const statusMap = isMobile() ? {
    [RFIDPortIdEnum.RFIDINSTOCK]: 0x00, // 在库
    [RFIDPortIdEnum.RFIDSOLD]: 0x10, // 已销售
    [RFIDPortIdEnum.RFIDBEENDISPATCHED]: 0x20, // 已调出
    [RFIDPortIdEnum.RFIDSCRAP]: 0x30, // 已废弃
  } : {
    [RFIDPortIdEnum.RFIDINSTOCK]: '0', // 在库
    [RFIDPortIdEnum.RFIDSOLD]: '1', // 已销售
    [RFIDPortIdEnum.RFIDBEENDISPATCHED]: '2', // 已调出
    [RFIDPortIdEnum.RFIDSCRAP]: '3', // 已废弃
  } // pc端的比较简单 直接写入就行
  const epcList = bodyList?.filter(_ => _.EPC).map(_ => _.EPC)
  // const epcList = ['38739204B0100000001']
  // 固定取bodyList里面的东西 方便处理
  switch (portId as RFIDPortIdEnum) {
    case RFIDPortIdEnum.RFIDINSTOCK:
    case RFIDPortIdEnum.RFIDSOLD:
    case RFIDPortIdEnum.RFIDSCRAP:
    case RFIDPortIdEnum.RFIDBEENDISPATCHED:
      if (epcList.length) {
        message.loading('写入中')
        const res: any = await getModifyResult(epcList, statusMap[portId])
        message.destroy()
        console.log('结果', JSON.stringify(res))
        const failList = res?.data?.failList

        if (failList.length) {
          error = true
          errorData = failList
          // 调整下一次要处理的列表
          body.bodyList = failList.map((_: string) => ({ EPC: _ }))
          message.warn(`写入失败epc码,${failList.join(',')}`)
        } else {
          message.success(`写入成功`)

        }
      } else {
        message.warn('需要设置的EPC码为空')
      }
      break;
    case RFIDPortIdEnum.RFIDEPCDESTORY:
      if (epcList.length) {
        message.loading('销毁中', 10 * 1000)
        const res: any = await getDestoryResult(epcList)
        message.destroy()
        if (!res?.data.epcList?.length) {
          message.success('销毁成功 ')
        } else {
          if (res?.data.epcList?.length) {
            error = true
            errorData = res?.data.epcList
            message.warn(res.data.epcList.join(',') + `未销毁`)
          } else {
            message.warn(`写入失败`)
          }
        }
        console.log(JSON.stringify(res), '写入结果')
      } else {
        message.warn('需要销毁的EPC码为空')
      }
      break;
    case RFIDPortIdEnum.ACTRFID: {
      // 给个默认的名字
      const actionName = body.actionName || 'actRfid'
      windowRFIDTriger.actEvent({ type: actionName })
      break;
    }
    default:
      message.warn('未指定的portId')
      break;
  }

  if (body.afterApi) {
    payload = await env.fetcher(body.afterApi, data)
  }

  return {
    error,
    errorData,
    payload,
  }
}

// keyStep脚本函数 专门处理keyStep脚本，识别到有通用化的趋势，故此抽出
// 第一个是执行剩下的按钮用的
export const KeyStepCommonFunction = async (scanAfterDo: ScanAfterDo[], data: any, env: any, props?: any, errorHandle?: (restScanDo: ScanAfterDo[], data: any, env: any, errorData: any) => any, reloadFun?: () => any) => {
  for (const key in scanAfterDo) {
    if (Object.prototype.hasOwnProperty.call(scanAfterDo, key)) {
      const element = scanAfterDo[key];
      const cmd = element.cmd
      let outFlag = false // 中断标识
      let payload // 返回集中存放
      let errorData = undefined // 错误数据 用于判断
      switch (cmd) {
        case "STEP_FRONT_PORT": {
          const result = await epc_front_port(element, data, env)
          outFlag = result.error
          payload = result.payload
          errorData = result.errorData
          break;
        }
        case 'STEP_PORT':
          const portBody = element.body as ScanAfterPort
          await expressLabels(portBody?.body, env.fetcher, props?.translate, props?.showModal === 1)
          if (portBody.afterApi) {
            payload = await env.fetcher(portBody.afterApi, data)
          }
          break
        case 'STEP_SHOW':
          const body = element.body as ScanAfterShow
          const { showMsg, showType, afterApi } = body
          if (showType == 10 || showType == 11 || showType == 12) {
            if (isMobile() && Shell.hasShell()) Shell.readVoice(showMsg)
          }
          if (showType == 0 || showType == 10) {
            // 有更新方法执行更行
            reloadFun?.()
            MSG._info(showMsg)
            if (afterApi) {
              payload = await env.fetcher(afterApi, data)
            }
          } else if (showType == 1 || showType == 11) {
            const confirm = await env.confirm(showMsg)
            if (confirm && afterApi) {
              payload = await env.fetcher(afterApi, data)
            }
          } else if (showType == 2 || showType == 12) {
            env.confirm(showMsg, undefined, undefined, false)
          }
          break
        case 'STEP_VARS':
          const varsBody = element.body as ScanAfterVars
          const formData = await env.prompt(varsBody.body, varsBody.data)
          if (formData !== false && varsBody.afterApi) {
            payload = await env.fetcher(varsBody.afterApi, { ...formData, ...data })
          }
          break
        case 'STEP_PRINT_LABEL':
          const printBody = element.body as ScanAfterLabelPrint
          const baseUrl = env.axiosInstance?.defaults?.baseURL ?? ''
          const labelTemplate = buildLabelTemplate(printBody.labelTemplate.tempContent)
          const templateDatas = setLabelTemplateData(labelTemplate, printBody.labelData, baseUrl)
          labelPrint({
            templateDatas,
            marginTop: 0,
            marginLeft: 0,
            pageWidth: printBody.labelTemplate.width || 210,
            pageHeight: printBody.labelTemplate.height || 297,
            direction: true,
            preview: false,
            printer: printBody.labelPrinter,
            count: 1
          })
          break
        default:
          break
      }


      if (outFlag) {
        errorHandle?.(scanAfterDo.slice(+key), data, env, errorData)
        return
      }
      if (payload) {
        if (payload.ok && payload.status == 20003) {
          await KeyStepCommonFunction(payload.data.scanAfterDo, data, env, props, errorHandle, reloadFun)
        } else {
          payload.msg && MSG._warning(payload.msg)
        }
      }
    }
  }
}
