import React from 'react';
import { Form, AutoComplete, Select, Button, Input, Spin, Tooltip } from 'kts-components-antd-x3';
import { InputProps } from 'kts-components-antd-x3/lib/input';
import { WrappedFormUtils } from 'kts-components-antd-x3/lib/form/Form';
import { IGood, LineAttributeType } from '../../../../../InvoiceController';
import Invoice from '../../../../..';
import RowMenu from './ui/RowMenu';
import TitleText from './ui/TitleText';
import ItemNameInput from './ui/ItemNameInput';
import ItemCodeInput from './ui/ItemCodeInput';
import {
  onChangeQuantity,
  onChangePriceIncludeTax,
  onChangePriceExcludeTax,
  onChangeLineAmountIncludeTax,
  onChangeLineAmountExcludeTax,
  onChangeTaxRate,
  onChangeItemName,
  onChangeItemCode,
} from './autoFillFn';
import { getItemNameWithShorthand } from '../../../../../tools/itemName';
import Drag from './ui/Drag';
import { nonScientificNotation } from '../../../../../tools/calculate';
import Expand from './ui/Expand';

export default (form: WrappedFormUtils) => {
  const { getFieldDecorator, getFieldValue } = form;

  const controller = Invoice.useInvoiceController();

  const rootElement = controller.useMemo(s => s.rootElement, []);

  /** 是否含税 */
  const isTaxIncluded = controller.useMemo(e => e.goodsListState.isTaxIncluded, []);

  /** 组件模式 */
  const model = controller.useMemo(e => e.model, []);

  /** 计算类型 */
  const calculateType = controller.useMemo(e => e.goodsListState.calculateType, []);

  /** 是否启用拖拽 */
  const isStart = controller.useMemo((e) => e.goodsListState.drag.isStart, []);

  /** 是否显示我方 */
  const isMyShow = controller.useMemo(e => e.goodsListState.isMyShow, []);

  /** 正在编辑的货物 */
  const editGood = controller.useMemo((e) => e.goodsListState.editGood, []);

  /** 正在编辑的货物 */
  const goodsList = controller.useMemo((e) => e.goodsListState.goodsList, []);

  /** 货物列表版本号 */
  const goodsListVersion = controller.useMemo((e) => e.goodsListState.goodsListVersion, []);

  /** 商品表格隐藏列 */
  const columnshide = controller.useMemo((e) => e.goodsListState.columnshide, []);

  /** 搜索条件 */
  const searchValue = controller.useMemo((e) => e.goodsListState.searchValue, []);

  /** 税率列表 */
  const taxRateList = controller.useMemo((e) => e.goodsListState.taxRateList, []);

  /** 单位列表 */
  const unitList = controller.useMemo((e) => e.goodsListState.unitList, []);

  /** 商品表格补充配置 */
  const columnsReplenish = controller.useMemo((e) => e.goodsListState.columnsReplenish, []);

  /** 扣除额 */
  const deduction = controller.useMemo((e) => e.goodsListState.deduction, []);

  /** 计算中启动字段 */
  const changeField = controller.useMemo((e) => e.calculatingField, []);

  /** 计算中启动字段 */
  const setChangeField = React.useCallback((value: string) => controller.run(async s => { s.calculatingField = value }), []);

  const onNumberValueChange = React.useCallback((e) => {
    const value = e?.target?.value;
    if (value) {
      return value.replace(/[^0-9-\.]/g, '');
    }
  }, [])

  /** 获取补充校验规则 */
  const getReplenishRules = React.useCallback((id: string) => {
    return columnsReplenish[id] ? columnsReplenish[id].rules || [] : []
  }, [columnsReplenish])

  /** 金额整数位限制,不传默认9位 */
  const priceIntegerDigit = controller.useMemo((e) => e.priceIntegerDigit || 9, []);

  /** 表头 */
  const columns = React.useMemo(() => {
    // console.log('====================================================');
    return [
      // {
      //   title: ' ',
      //   key: 'drag',
      //   width: 40,
      //   align: 'center',
      //   render: (_: any, record: IGood) => <Drag record={record} />
      // },
      {
        title: ' ',
        key: 'expand',
        width: 50,
        align: 'center',
        render: (_: any, record: IGood) => <Expand record={record} />
      },
      {
        title: '序号',
        key: 'serialNo',
        dataIndex: 'serialNo',
        width: 50,
        render: (e: number) => <span style={{ padding: '0 10px' }}>{e}</span>,
      },
      {
        title: '商品编码',
        key: 'itemCode',
        width: 119,
        render: (_: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('itemCode', {
                  initialValue: editGood.itemCode,
                  rules: [
                    ...getReplenishRules('itemCode'),
                    { pattern: /^.{1,19}$/, message: '商品编码长度不能超过19位' },
                  ]
                })(
                  <ItemCodeInput
                    onChange={async () => {
                      await onChangeItemCode(controller, form, record);
                      // await onChangeLineAmountIncludeTax(controller, form, record);
                    }}
                  />
                )}
              </Form.Item>
            )
          } else {
            return <span style={{ padding: '0 10px' }}>{record.itemCode}</span>
          }
        }
      },
      {
        title: <TitleText required >项目名称</TitleText>,
        key: 'itemName',
        render: (_: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                <div style={{ display: 'flex' }} >
                  {getFieldDecorator('itemName', {
                    initialValue: record.itemName,
                    rules: [
                      ...getReplenishRules('itemName'),
                      {
                        validator: async (_, __, callback) => {
                          await controller.wait();
                          const value = controller.state.goodsListState.editGood;
                          if (!value?.itemName && !value?.itemNameSelf) {
                            callback('项目名称不能为空');
                          } else {
                            return;
                          }
                        }
                      }
                    ]
                  })(
                    <ItemNameInput
                      editGood={editGood}
                      shorthand={editGood.shorthand}
                      onChange={() => {
                        onChangeItemName(controller, form, record);
                      }}
                    />
                  )}
                  <div className="kts-invoice-operate-goods-list-able-list-itemName-import">
                    {controller.getGoodsList && model !== 'readOnly' && (
                      <Tooltip title="点击从商品管理中添加商品信息">
                        <Button
                          onClick={controller.pipeline(async s => { s.goodsListState.importGoods.isVisibleDrawer = true })}
                          type="link"
                          icon="plus-circle"
                        />
                      </Tooltip>
                    )}
                  </div>
                </div>
              </Form.Item>
            );
          } else {
            return (
              <MyItemNameDiv
                valueT={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemNameSelf || '' }), searchValue)}
                valueF={formatSearch(getItemNameWithShorthand({ shorthand: record.shorthand, full: record.itemName || '' }), searchValue)}
                isMyShow={isMyShow}
              />
            )
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['itemModelName']?.rules} >规格型号</TitleText>,
        key: 'itemModelName',
        width: 119,
        render: (_: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('itemModelName', {
                  initialValue: isMyShow ? editGood.itemModelNameSelf : editGood.itemModelName,
                  rules: getReplenishRules('itemModelName'),
                })(
                  <MyInput
                    onChange={async () => {
                      await controller.wait()
                      const key = isMyShow ? 'itemModelNameSelf' : 'itemModelName';
                      const value = {} as any;
                      value[key] = form.getFieldsValue().itemModelName;
                      controller.setEditGood(value);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return (
              <MyItemNameDiv
                valueT={formatSearch(record.itemModelNameSelf, searchValue)}
                valueF={formatSearch(record.itemModelName, searchValue)}
                isMyShow={isMyShow}
              />
            )
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['unit']?.rules} >单位</TitleText>,
        key: 'unit',
        width: 70,
        render: (_: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('unit', {
                  initialValue: editGood.unit,
                  rules: getReplenishRules('unit'),
                })(
                  <AutoComplete
                    style={{ width: '100%' }}
                    dataSource={unitList}
                    getPopupContainer={() => rootElement || document.body}
                    onChange={async () => {
                      await controller.wait()
                      controller.setEditGood({ unit: form.getFieldsValue().unit });
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{record.unit}</span>;
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['quantity']?.rules} >数量</TitleText>,
        dataIndex: 'quantity',
        key: 'quantity',
        align: 'right',
        width: 149,
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('quantity', {
                  initialValue: nonScientificNotation(editGood.quantity),
                  getValueFromEvent: onNumberValueChange,
                  rules: [
                    ...getReplenishRules('quantity'),
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '数量必须为数字' },
                    {
                      validator: async (_, value, callback) => {
                        await controller.wait();
                        const isvalue = !!value || value === 0;
                        const isPrice = !!getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') || getFieldValue(isTaxIncluded ? 'priceIncludeTax' : 'priceExcludeTax') === 0;
                        if (isvalue || isPrice === isvalue) return;
                        callback('请输入数量');
                      }
                    }
                  ],
                })(
                  <MyInput
                    style={{ textAlign: 'right' }}
                    maxLength={16}
                    loading={isCipher(changeField, "quantity")}
                    onChange={async () => {
                      setChangeField('quantity');
                      await onChangeQuantity(controller, form, record);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['priceIncludeTax']?.rules} >单价(含税)</TitleText>,
        dataIndex: 'priceIncludeTax',
        key: 'priceIncludeTax',
        align: 'right',
        width: 149,
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('priceIncludeTax', {
                  initialValue: nonScientificNotation(editGood.priceIncludeTax),
                  getValueFromEvent: onNumberValueChange,
                  rules: [
                    ...getReplenishRules('priceIncludeTax'),
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
                    {
                      validator: async (_, value, callback) => {
                        await controller.wait();
                        const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
                        const isvalue = !!value || value === 0;
                        if (isvalue || isQuantity === isvalue) return;
                        callback('请输入单价');
                      }
                    }
                  ],
                })(
                  <MyInput
                    style={{ textAlign: 'right' }}
                    maxLength={16}
                    loading={isCipher(changeField, 'priceIncludeTax')}
                    onChange={() => {
                      setChangeField('priceIncludeTax');
                      onChangePriceIncludeTax(controller, form, record);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['priceExcludeTax']?.rules} >单价(不含税)</TitleText>,
        dataIndex: 'priceExcludeTax',
        key: 'priceExcludeTax',
        align: 'right',
        width: 149,
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('priceExcludeTax', {
                  initialValue: nonScientificNotation(editGood.priceExcludeTax),
                  getValueFromEvent: onNumberValueChange,
                  rules: [
                    ...getReplenishRules('priceExcludeTax'),
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '单价必须为数字' },
                    {
                      validator: async (_, value, callback) => {
                        await controller.wait();
                        const isQuantity = !!getFieldValue('quantity') || getFieldValue('quantity') === 0;
                        const isvalue = !!value || value === 0;
                        if (isvalue || isQuantity === isvalue) return;
                        callback('请输入单价');
                      }
                    }
                  ],
                })(
                  <MyInput
                    style={{ textAlign: 'right' }}
                    maxLength={16}
                    loading={isCipher(changeField, 'priceExcludeTax')}
                    onChange={() => {
                      setChangeField('priceExcludeTax');
                      onChangePriceExcludeTax(controller, form, record);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{nonScientificNotation(value)}</span>;
          }
        },
      },
      {
        title: <TitleText required >金额(含税)</TitleText>,
        dataIndex: 'lineAmountIncludeTax',
        key: 'lineAmountIncludeTax',
        width: 119,
        align: 'right',
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('lineAmountIncludeTax', {
                  initialValue: editGood.lineAmountIncludeTax,
                  getValueFromEvent: onNumberValueChange,
                  rules: [
                    ...getReplenishRules('lineAmountIncludeTax'),
                    { required: true, message: '金额不能为空' },
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
                    {
                      validator: async (_, value, callback) => {
                        if (`${value}`.split('.')[0].length > priceIntegerDigit) {
                          callback(`金额整数部分不能大于${priceIntegerDigit}位，小数点后最多2位`);
                        }
                      }
                    },
                    {
                      validator: async (_, value, callback) => {
                        if (deduction && parseFloat(value) <= deduction) {
                          callback('扣除额不能大于等于价税合计');
                        }
                      }
                    },
                  ],
                })(
                  <MyInput
                    style={{ textAlign: 'right' }}
                    loading={isCipher(changeField, 'lineAmountIncludeTax')}
                    onChange={() => {
                      setChangeField('lineAmountIncludeTax');
                      onChangeLineAmountIncludeTax(controller, form, record);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
          }
        },
      },
      {
        title: <TitleText required >金额(不含税)</TitleText>,
        dataIndex: 'lineAmountExcludeTax',
        key: 'lineAmountExcludeTax',
        align: 'right',
        width: 119,
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index && model !== 'prefab') {
            return (
              <Form.Item>
                {getFieldDecorator('lineAmountExcludeTax', {
                  initialValue: editGood.lineAmountExcludeTax,
                  getValueFromEvent: onNumberValueChange,
                  rules: [
                    ...getReplenishRules('lineAmountExcludeTax'),
                    { required: true, message: '金额不能为空' },
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '金额必须为数字' },
                    {
                      validator: async (_, value: string, callback) => {
                        if (`${value}`.split('.')[0].length > priceIntegerDigit) {
                          callback(`金额整数部分不能大于${priceIntegerDigit}位，小数点后最多2位`);
                        }
                      }
                    },
                  ],
                })(
                  <MyInput
                    style={{ textAlign: 'right' }}
                    loading={isCipher(changeField, 'lineAmountExcludeTax')}
                    onChange={() => {
                      setChangeField('lineAmountExcludeTax');
                      onChangeLineAmountExcludeTax(controller, form, record);
                    }}
                  />,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{formatSearch(parseFloat(value).toFixed(2), searchValue)}</span>;
          }
        },
      },
      {
        title: <TitleText required >税率</TitleText>,
        dataIndex: 'taxRate',
        key: 'taxRate',
        align: 'right',
        width: 75,
        render: (value: string, record: IGood) => { 
          if (editGood?.$index === record.$index && !(model === 'prefab' && calculateType === '3')) { 
            // 如存在按税编异步获取税率的能力，并且当前行有税编但还没拿到专属税率列表，
            // 为避免“接口未返回时误用全局 taxRateList”，暂不展示全局税率，先展示一个 loading 状态，
            // 等 record.goodsTaxRateList 赋值后再渲染真正的下拉选项。
            if (controller.getGoodsTaxRateList && record.taxClassificationCode && !record.goodsTaxRateList) {
              return (
                <div style={{ textAlign: 'center' }}>
                  <Spin size="small" />
                </div>
              );
            }

            // 只有在没有按税编单独税率逻辑时，才退回使用全局 taxRateList
            const options =
              record.goodsTaxRateList ||
              (!controller.getGoodsTaxRateList || !record.taxClassificationCode ? taxRateList : []);

            return (
              <Form.Item>
                {getFieldDecorator('taxRate', {
                  initialValue: editGood.taxRate,
                  rules: [
                    ...getReplenishRules('taxRate'),
                    { required: true, message: '请选择税率' },
                    { pattern: /^[+-]?(0|([1-9]\d*))(\.\d+)?$/, message: '请选择正确税率' },
                  ],
                })(
                  <Select
                    className="kts-invoice-operate-goods-list-table-tax-rate"
                    dropdownMenuStyle={{ textAlign: "right" }}
                    showArrow={false}
                    style={{ width: '100%' }}
                    getPopupContainer={() => rootElement || document.body}
                    onChange={() => {
                      setChangeField('taxRate');
                      onChangeTaxRate(controller, form, record);
                    }}
                  >
                    {options.map((e, i) => {
                      return (
                        <Select.Option key={i} value={e}>
                          {e}%
                        </Select.Option>
                      );
                    })}
                  </Select>,
                )}
              </Form.Item>
            );
          } else {
            return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '免税' : `${value}%`}</span>;
          }
        },
      },
      {
        title: <TitleText rules={columnsReplenish['taxAmount']?.rules} >税额</TitleText>,
        dataIndex: 'taxAmount',
        key: 'taxAmount',
        align: 'right',
        width: 119,
        render: (value: string, record: IGood) => {
          if (editGood?.$index === record.$index) {
            return getFieldDecorator('taxAmount', {
              initialValue: editGood.taxAmount,
              rules: getReplenishRules('taxAmount'),
            })(<MyDiv loading={isCipher(changeField, 'taxAmount')} />);
          } else {
            return <span style={{ padding: '0 10px' }}>{isDutyFree(record) ? '***' : parseFloat(value).toFixed(2)}</span>;
          }
        },
      },
      {
        title: '行性质',
        dataIndex: 'lineAttribute',
        key: 'lineAttribute',
        width: 70,
        render: (e: any) => {
          switch (e) {
            case LineAttributeType.折扣行:
              return <span style={{ padding: '0 10px' }}>折扣行</span>
            case LineAttributeType.被折扣行:
              return <span style={{ padding: '0 10px' }}>被折扣行</span>
            case LineAttributeType.赠品行:
              return <span style={{ padding: '0 10px' }}>赠品行</span>
            case LineAttributeType.折让行:
              return <span style={{ padding: '0 10px' }}>折让行</span>
            case LineAttributeType.正常:
              return <span style={{ padding: '0 10px' }}>正常行</span>
            default:
              return <span style={{ padding: '0 10px' }}>{e}</span>
          }
        }
      },
      {
        title: '操作',
        key: 'operating',
        align: 'right',
        width: 130,
        fixed: 'right',
        render: (_value: string, record: IGood) => <RowMenu key={record.lineAttribute} goods={record} />,
      },
    ]
      // 筛选隐藏
      .filter(e => {
        return e.key ? columnshide.indexOf(e.key) < 0 : false;
      })
      // 含税不含税
      .filter((e) => {
        if (isTaxIncluded) {
          return !(e.key === 'priceExcludeTax' || e.key === 'lineAmountExcludeTax');
        } else {
          return !(e.key === 'priceIncludeTax' || e.key === 'lineAmountIncludeTax');
        }
      })
      // 是否启动拖拽
      .filter(e => e.key !== 'drag' || isStart)
      // 是否启动展开
      .filter(e => e.key === 'expand' ? goodsList.some(e => !!e.children) : true)
      // 只读
      .filter(e => {
        if (model === 'readOnly') {
          return e.key !== 'operating';
        } else {
          return true;
        }
      })
      .map((e) => {
        return {
          ...e,
          ellipsis: true,
        };
      }) as any[];
  }, [isTaxIncluded, editGood, goodsList, controller, changeField, deduction, isMyShow, searchValue, model, columnsReplenish, columnshide, isStart, goodsListVersion]);
  
  return controller.setColumnsConfig ? controller.setColumnsConfig(columns) : columns;
};

/** 字段 */
function isCipher(name?: string, field?: string) {
  if (!name || !field) return false;
  return name !== field;
}

class MyInput extends React.Component<InputProps & { loading?: boolean }> {
  render() {
    if (this.props.loading) {
      return (
        <Spin size="small">
          <Input {...this.props} autoComplete="off" />
        </Spin>
      )
    } else {
      return <Input {...this.props} autoComplete="off" />
    }
  }
}

class MyDiv extends React.Component<{ value?: any, loading?: boolean }> {
  render() {
    if (this.props.loading) {
      return (
        <Spin size="small">
          <span style={{ padding: '0 10px' }}>{this.props.value}</span>
        </Spin>
      )
    } else {
      return <span style={{ padding: '0 10px' }}>{this.props.value}</span>
    }
  }
}

class MyItemNameDiv extends React.Component<{ valueT?: React.ReactNode, valueF?: React.ReactNode, isMyShow: boolean }> {
  render(): React.ReactNode {

    const { isMyShow, valueT, valueF } = this.props;

    if (isMyShow) {
      if (valueT) {
        return (
          <Tooltip title={valueT}>
            <span style={{ padding: '0 10px', color: '#0074ff', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{valueT}</span>
          </Tooltip>
        )
      } else {
        return (
          <Tooltip title={valueF}>
            <span style={{ padding: '0 10px', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{valueF}</span>
          </Tooltip>
        )
      }
    } else {
      if (valueF) {
        return (
          <Tooltip title={valueF}>
            <span style={{ padding: '0 10px', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{valueF}</span>
          </Tooltip>
        )
      } else {
        return (
          <Tooltip title={valueT}>
            <span style={{ padding: '0 10px', color: '#0074ff', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{valueT}</span>
          </Tooltip>
        )
      }
    }
  }
}

/** 格式搜索结果 */
function formatSearch(value?: string, search?: string) {
  if (!value || !search) return value;

  const __html = ucoding(value).split(new RegExp(ucoding(search), 'g')).map(e => dcoding(e)).join(`<span class="kts-invoice-operate-goods-list-table-search-protrude" >${search}</span>`);
  return <span dangerouslySetInnerHTML={{ __html }} />
}

/** 编码 */
function ucoding(v: string): string {
  return v.split('').map(e => `U${e.charCodeAt(0)}E`).join('');
}

/** 解码 */
function dcoding(v: string): string {
  return v.split('U').map(e => e ? String.fromCharCode(parseInt(e.replace('E', ''))) : '').join('');
}

/** 是否免税 */
function isDutyFree(record: IGood): boolean {
  return (record.taxFreeType as any) === 1 && record.favouredPolicyName === '免税';
}
