import { createContext, useContext, useEffect, useState } from 'react';
import { Form, Input, Row, Col, Select, DatePicker, Space, Button } from 'antd';
import { objectMapper, at, isEmpty } from '@/utils/commons';
import { DATE_FORMAT } from '@/config';
import useFormStore from '@/stores/Form';
import usePresets from '@/hooks/usePresets';
import { useTranslation } from 'react-i18next';

const { RangePicker } = DatePicker;

const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
  const { t } = useTranslation();
  const presets = usePresets();
  const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
  const [formValuesToSub, setFormValuesToSub] = useFormStore((state) => [state.formValuesToSub, state.setFormValuesToSub]);
  const [form] = Form.useForm();
  const { sort,  hides, shows, fieldProps } = {
    sort: '',
    // initialValue: '',
    fieldProps: '',
    hides: [],
    shows: [],
    ...props.defaultValue,
  };
  const { confirmText } = props;
  const readValues = { ...initialValue, ...formValues };

  const formValuesMapper = (values) => {
    const destinationObject = {
      'referenceNo': { key: 'referenceNo' },
      'dates': [
        { key: 'startdate', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
        { key: 'enddate', transform: (arrVal) => (arrVal ? arrVal[1].format(DATE_FORMAT) : '') },
      ],
      'invoiceStatus': { key: 'invoiceStatus', transform: (value) => value?.value || value?.key || '', default: '' },
    };
    let dest = {};
    const { dates, ...omittedValue } = values;
    dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
    for (const key in dest) {
      if (Object.prototype.hasOwnProperty.call(dest, key)) {
        dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
      }
    }
    // omit empty
    Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
    return dest;
  };

  useEffect(() => {
    const dest = formValuesMapper(formValues);
    setFormValuesToSub(dest);
    return () => {};
  }, []);

  const onFinish = (values) => {
    console.log('Received values of form, origin form value: ', values);
    const dest = formValuesMapper(values);
    console.log('form value send to onSubmit:', dest);
    const str = new URLSearchParams(dest).toString();
    setFormValues(values);
    setFormValuesToSub(dest);
    if (typeof onSubmit === 'function') {
      onSubmit(null, dest, values, str);
    }
  };

  const handleReset = () => {
    form.setFieldsValue({
      // 'DateType': undefined,
    });
    if (typeof onReset === 'function') {
      onReset();
    }
  };
  const onValuesChange = (changedValues, allValues) => {

    const dest = formValuesMapper(allValues);
    setFormValues(allValues);
    setFormValuesToSub(dest);
    // console.log('form onValuesChange', Object.keys(changedValues), args);
  };
  return (
    <>
      <Form form={form} name='advanced_search' className='orders-search-form' onFinish={onFinish} onValuesChange={onValuesChange}>
        {/* <EditableContext.Provider value={form}> */}
        <Row gutter={16}>
          {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, form, presets, t })}
          {/* 'textAlign': 'right' */}
          <Col flex='1 0 90px' className='flex justify-normal items-start' >
            <Space align='center'>
              <Button size={'middle'} type='primary' htmlType='submit'>
                {confirmText || t('Search')}
              </Button>
              {/* <Button size="small" onClick={onReset}>
                重置
              </Button> */}
            </Space>
          </Col>
        </Row>
        {/* </EditableContext.Provider> */}
      </Form>
    </>
  );
};

function getFields(props) {
  const { fieldProps, form, presets, t } = props;
  const bigCol = 4 * 2;
  const midCol = 6;
  const layoutProps = {
    // gutter: { xs: 8, sm: 8, lg: 16 },
    lg: { span: 4 },
    md: { span: 8 },
    sm: { span: 12 },
    xs: { span: 24 },
  };
  const item = (name, sort = 0, render, col) => {
    const customCol = col || 4;
    const mdCol = customCol * 2;
    return {
      'key': '',
      sort,
      name,
      render,
      'hide': false,
      'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol }, flex: mdCol < 8 ? '1 0' : '' },
    };
  };
  let baseChildren = [];
  baseChildren = [
    item(
      'referenceNo',
      99,
      <Form.Item name='referenceNo'>
        <Input placeholder={t('group:RefNo')} allowClear />
      </Form.Item>,4
    ),
    item(
      'invoiceStatus',
      99,
      <Form.Item name={`invoiceStatus`} initialValue={at(props, 'initialValue.invoiceStatus')[0] || (fieldProps?.invoiceStatus?.show_all ? { key: '-1', label: '所有' } : undefined)}>
        <Select style={{ width: '100%' }} placeholder='所有状态' labelInValue>
          {fieldProps?.invoiceStatus?.show_all && (
            <Select.Option key='所有' value='-1'>
              所有
            </Select.Option>
          )}
          <Select.Option key='已成行' value='1'>
            已成行
          </Select.Option>
          <Select.Option key='未成行' value='0'>
            未成行
          </Select.Option>
        </Select>
      </Form.Item>,
      3
    ),
    item(
      'dates',
      99,
      <Form.Item name={'dates'} {...fieldProps.dates} initialValue={at(props, 'initialValue.dates')[0]}>
        {/* <DatePickerCharts isform={true} {...fieldProps.dates} form={form} /> */}
        <RangePicker
          allowClear={true}
          inputReadOnly={true}
          presets={presets}
          // defaultValue={toJS(arrivalDateRange)}
          placeholder={['From', 'Thru']}
          // onChange={(dateRange) => {
          // reservationStore.updatePropertyValue('arrivalDateRange', dateRange == null ? [] : dateRange)
          // }}
        />
      </Form.Item>,
      fieldProps?.dates?.col || midCol
    ),
  ];
  baseChildren = baseChildren
    .map((x) => {
      x.hide = false;
      if (props.sort === undefined) {
        return x;
      }
      const tmpSort = props.sort;
      for (const key in tmpSort) {
        if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
          if (x.name === key) {
            x.sort = tmpSort[key];
          }
        }
      }
      return x;
    })
    .map((x) => {
      if (props.hides.length === 0 && props.shows.length === 0) {
        return x;
      }
      if (props.hides.length === 0) {
        x.hide = !props.shows.includes(x.name);
      } else if (props.shows.length === 0) {
        x.hide = props.hides.includes(x.name);
      }
      return x;
    })
    .filter((x) => !x.hide)
    .sort((a, b) => {
      return a.sort < b.sort ? -1 : 1;
    });
  const children = [];
  const leftStyle = {}; // { borderRight: '1px solid #dedede' };
  for (let i = 0; i < baseChildren.length; i++) {
    let style = {}; // { padding: '0px 2px' };
    style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
    style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
    const Item = (
      <Col key={String(i)} style={style} {...layoutProps} {...baseChildren[i].col}>
        {baseChildren[i].render}
      </Col>
    );
    children.push(Item);
  }
  return children;
}

export default SearchForm;
