import React from "react";
import Form from 'antd/lib/form';
import InputNumber from 'antd/lib/input-number';
import Select from 'antd/lib/select';
import Radio from 'antd/lib/Radio';
import { Spinner } from "../../../../components";
import Button from '../../../../components/Button'
import { CloseIcon } from "../../../../components/icons";
import { Api } from '../../../../types';
import message from 'antd/lib/message';
import { RendererEnv } from '../../../../env';
import { FormInstance } from "antd/es/form";
import { Template, LabelData, PrinterParam } from '../type';
import { buildLabelTemplate, setLabelTemplateData } from "../../../../utils/print/util";
import { billPrint } from "../../../../utils/print";
import moment from "moment";

const { Option } = Select;

interface BillPrintProps {
  labelDataApi: Api; // 获取标签数据数组
  templateApi: Api; // 获取标签模板
  callbackApi?: any; // 打印回调，发送打印时间
  labelId?: string;
  env: RendererEnv
  classnames: (...args: any[]) => string;
  ctx: {
    items: Array<any>; // 选中的行数据
    rows: Array<any>; // 选中的行数据
    selectedItems: Array<any>; // 选中的行数据
    unSelectedItems: Array<any>; // 未选中的行数据
    ids: string; // 多个 id 值用英文逗号隔开的字符串，前提是行数据中有 id 字段，或者有指定的 primaryField 字段
    primaryField?: string; // CRUD 设置 ID 字段名
    [key: string]: any; // 第一行的所有行数据也会包含进去
  };
  onHide: (e?: any) => void; // modal关闭回调
  isRow?: boolean; // 是否行内按钮
  query?: any;
  filterKey?: string; // CRUD filter的name的值
  [key: string]: any;
  printers: string[]
  baseUrl: string
  modalContainer?: () => HTMLElement
  popupContainer?: () => HTMLElement
}

interface BillPrintState {
  previewLoading: boolean
  templates: Template[]
}

interface BillPrintFormValues {
  printer: string // 打印机名
  label: string // 标签模板名
  // pageSize: string // 纸张类型
  // pageWidth: number // 纸张宽度mm
  // pageHeight: number // 纸张高度mm
  /** 纵向/横向 */
  direction: 0 | 1
  /** 打印份数  */
  count: number
}

export default class BillPrint extends React.Component<BillPrintProps, BillPrintState> {

  formRef = React.createRef<FormInstance<BillPrintFormValues>>()

  cacheLabelData?: LabelData

  constructor(props: BillPrintProps) {
    super(props)
    this.state = {
      previewLoading: false,
      templates: []
    }
  }

  async componentDidMount() {
    const templates = await this.getTemplates()
    this.setState({ templates }, () => {
      this.formRef.current?.setFieldsValue({
        label: templates[0].tempName
      })
      this.handleBillPreview()
    })
  }

  componentWillUnmount() {
    this.cacheLabelData = undefined
  }

  // 获取模板数据
  async getTemplates() {
    const { env, templateApi } = this.props
    const templates: Template[] = await env.fetcher(templateApi).then(res => {
      if (res.status === 0) {
        return Promise.resolve(res.data)
      } else {
        return Promise.resolve([])
      }
    })
    return templates
  }

  async getLabelData() {
    if (this.cacheLabelData) {
      return this.cacheLabelData
    }
    const { env, ctx, labelDataApi, primaryField, isRow } = this.props
    // printType: 0选中数据  1全量打印  2行内打印
    let data: any = {}
    if (isRow) {
      data = ctx
      data.printType = 2
    } else {
      if (!ctx?.ids) {
        message.info('请先选择行数据')
        return
      }
      data.printType = 0
      data.ids = ctx.ids
      data.primaryField = primaryField
    }
    const res = await env.fetcher(labelDataApi, data)
    if (res.status === 0) {
      const data = res.data as LabelData
      this.cacheLabelData = data
      return data
    } else {
      message.error(res.msg)
      return null
    }
  }

  async handleBillPreview() {
    this.setState({ previewLoading: true })
    const values = await this.formRef.current!.validateFields()
    const labelData = await this.getLabelData()

    const template = this.state.templates.find(temp => temp.tempName === values.label)
    if (labelData && template) {
      const { tempContent, tableColumn, width, height } = template
      const labelTemplate = buildLabelTemplate(tempContent)
      const templateDatas = setLabelTemplateData(labelTemplate, labelData.items, this.props.baseUrl, tableColumn)
      const param: PrinterParam = {
        ...values,
        pageWidth: width,
        pageHeight: height,
        preview: true,
        direction: values.direction === 0,
        arrange: false,
        marginTop: 0,
        marginLeft: 0,
        rowSpacing: 0,
        colSpacing: 0
      }
      billPrint({
        ...param,
        templateDatas
      }, () => {
        this.setState({ previewLoading: false })
      })
    }
  }

  async handleBillPrint() {
    const values = await this.formRef.current!.validateFields()
    const labelPrintData = await this.getLabelData()
    const template = this.state.templates.find(temp => temp.tempName === values.label)
    if (labelPrintData && template) {
      const { tempContent, tableColumn, width, height } = template
      const labelTemplate = buildLabelTemplate(tempContent)
      const templateDatas = setLabelTemplateData(labelTemplate, labelPrintData.items, this.props.baseUrl, tableColumn)
      const param: PrinterParam = {
        ...values,
        pageWidth: width,
        pageHeight: height,
        preview: false,
        direction: values.direction === 0,
        arrange: false,
        marginTop: 0,
        marginLeft: 0,
        rowSpacing: 0,
        colSpacing: 0
      }
      billPrint({
        ...param,
        templateDatas
      }, () => {
        this.savePrintInfo()
      })
    }
  }

  savePrintInfo() {
    // 获取保存请求的地址
    const { env: { fetcher }, ctx, callbackApi } = this.props
    if (!callbackApi) return
    const PRINT_TIME = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
    callbackApi.data = {
      callbackList: {
        ...callbackApi.data,
        PRINT_TIME
      }
    }
    fetcher(callbackApi, { ids: ctx?.ids })
  }

  render() {
    const { classnames: cx, translate: __, popupContainer, printers, onHide } = this.props
    const { previewLoading, templates } = this.state
    const templateNames = templates.map(item => item.tempName)

    return (
      <>
        <div className={cx('Modal-header')}>
          <div className={cx('Modal-title')}>
            {'单据打印'}
            <a
              data-tooltip={__('Dialog.close')}
              onClick={(e) => onHide(e)}
              className={cx('Modal-close')}
            >
              <CloseIcon />
            </a>
          </div>
        </div>
        <div className={cx('Modal-body')}>
          <div className='print-form-container'>
            <div className='preview-container'>
              <Spinner size="md" overlay show={previewLoading} />
              <iframe id='label-preview' width='100%' height='100%'></iframe>
            </div>
            <Form style={{ width: 300, marginLeft: -20, marginRight: 40 }} ref={this.formRef} colon={false} labelCol={{ span: 8, offset: 1 }} wrapperCol={{ span: 16, offset: 1 }}>
              <Form.Item name="printer" label={__('CRUD.printer')} initialValue={printers[0] || ''} rules={[{ required: true, message: `${__('CRUD.selectPrinter')}` }]}>
                <Select
                  getPopupContainer={popupContainer}
                  dropdownClassName='label-print-selector' >
                  {printers.map(item => <Option key={item} value={item}>{item}</Option>)}
                </Select>
              </Form.Item>
              <Form.Item name="label" label={__('CRUD.selectLabel')} rules={[{ required: true, message: `${__('CRUD.select_Label')}` }]}>
                <Select
                  getPopupContainer={popupContainer}
                  dropdownClassName='label-print-selector'
                  onChange={() => this.handleBillPreview()}>
                  {templateNames?.map(item => <Option key={item} value={item} >{item}</Option>)}
                </Select>
              </Form.Item>

              {/* <Form.Item name="pageSize" label={__('CRUD.pageSize')} initialValue={pageOptions[0].value} rules={[{ required: true, message: `${__('CRUD.selectPage')}` }]}>
                <Select
                  getPopupContainer={popupContainer}
                  dropdownClassName='label-print-selector'
                  onChange={(value: string) => {
                    const [pageWidth, pageHeight] = sizeOptions[value]
                    this.formRef.current?.setFieldsValue({
                      pageWidth: pageWidth,
                      pageHeight: pageHeight,
                    })
                  }}
                >
                  {pageOptions.map(item => <Option key={item.value} value={item.value}>{item.label}</Option>)}
                </Select>
              </Form.Item> */}

              {/* <Row gutter={24}>
                <Col span={6} style={{ position: 'relative', top: 2, padding: 0, textAlign: 'right' }}>
                  宽*高(mm)
                </Col>
                <Col span={8} style={{ paddingLeft: 15 }}>
                  <Form.Item style={{ width: 140 }} name="pageWidth" initialValue={sizeOptions[pageOptions[0].value][0]} rules={[{
                    validator: async (rule, value) => {
                      if (value < 0 || value > 1000) {
                        throw new Error(`${__('CRUD.fillIn')}1-1000`);
                      }
                    }
                  }]} >
                    <InputNumber className='w-full' min={0} max={1000} />
                  </Form.Item>
                </Col>
                <Col span={8} style={{ marginLeft: 12 }}>
                  <Form.Item style={{ width: 140 }} name="pageHeight" initialValue={sizeOptions[pageOptions[0].value][1]} rules={[{
                    validator: async (rule, value) => {
                      if (value < 0 || value > 1000) {
                        throw new Error(`${__('CRUD.fillIn')}1-1000`);
                      }
                    }
                  }]}>
                    <InputNumber className='w-full' min={0} max={1000} />
                  </Form.Item>
                </Col>
              </Row> */}
              <Form.Item name="direction" label={__('direction')}
                initialValue={0}
                rules={[{ required: true, }]}>
                <Radio.Group onChange={() => this.handleBillPreview()}>
                  <Radio value={0} style={{ marginRight: 32 }}>{__('vertical')}</Radio>
                  <Radio value={1}>{__('horizontal')}</Radio>
                </Radio.Group>
              </Form.Item>
              <Form.Item name="count" label={__('CRUD.copies')} initialValue={1} rules={[{
                validator: async (rule, value) => {
                  if (value < 1 || value > 10000) {
                    throw new Error(`${__('CRUD.fillIn')}1-10000`);
                  }
                }
              }]}>
                <InputNumber className='input-count' min={1} max={10000} formatter={value => value ? Number(value).toFixed(0) : ''} />
              </Form.Item>
            </Form>
          </div>
        </div>
        <div className={cx('Modal-footer')} >
          <Button level="primary" onClick={this.handleBillPrint.bind(this)} >{__('print')}</Button>
          <Button onClick={(e) => onHide(e)}>取消</Button>
        </div >
      </>
    )
  }

}