import { useEffect } from 'react';
import { Form, Input, Row, Col, Select, DatePicker, Space, Button, Checkbox } from 'antd';
import { objectMapper, at } from '@/utils/commons';
import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
import useFormStore from '@/stores/Form';
import { useDatePresets } from '@/hooks/useDatePresets';
import { useProductsTypes } from '@/hooks/useProductsSets';
import { useTranslation } from 'react-i18next';

import { fetchJSON } from '@/utils/request';
import { HT_HOST } from '@/config';

import SearchInput from './SearchInput';
import AuditStateSelector from './AuditStateSelector';
import DeptSelector from './DeptSelector';

//供应商列表
export const fetchVendorList = async (q) => {
  const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/VendorList`, { q })
  return errcode !== 0 ? [] : result
}

const { RangePicker } = DatePicker;

export const SelectProductsTypes = ({...props}) => {
  const productsTypes = useProductsTypes();
  const { t } = useTranslation();
  return (
    <>
      <Select labelInValue allowClear placeholder={t('products:ProductType')} options={productsTypes} {...props}/>
    </>
  );
};

const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, formLayout, loading, ...props }) => {
  const { t } = useTranslation();
  const presets = useDatePresets();
  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, fieldComProps } = {
    sort: '',
    // initialValue: '',
    fieldProps: '',
    fieldComProps: '',
    hides: [],
    shows: [],
    ...props.fieldsConfig,
  };
  const readValues = { ...initialValue, ...formValues };

  const formValuesMapper = (values) => {
    const destinationObject = {
      'keyword': { key: 'keyword', transform: (value) => value || '' },
      'referenceNo': { key: 'referenceNo', transform: (value) => value || '' },
      'dates': [
        { key: 'startdate', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
        { key: 'enddate', transform: (arrVal) => (arrVal ? arrVal[1].format(DATE_FORMAT) : '') },
        { key: 'starttime', transform: (arrVal) => (arrVal ? arrVal[0].format(DATE_FORMAT) : '') },
        { key: 'endtime', transform: (arrVal) => (arrVal ? arrVal[1].format(SMALL_DATETIME_FORMAT) : '') },
      ],
      'invoiceStatus': { key: 'invoiceStatus', transform: (value) => value?.value || value?.key || '', default: '' },
      'audit_state': { key: 'audit_state', transform: (value) => value?.value || value?.key || '', default: '' },
      'agency': {
        key: 'agency',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
        },
      },
      'year': [
        { key: 'year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') },
      ],
      'products_types': {
        key: 'products_types',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
        },
      },
      'dept': {
        key: 'dept',
        transform: (value) => {
          console.log(value);
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : '';
        },
      },
    };
    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: \n', values);
    const dest = formValuesMapper(values);
    console.log('form value send to onSubmit:\n', 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);
  };

  const onFinishFailed = ({ values, errorFields }) => {
    console.log('form validate failed', '\nform values:', values, '\nerrorFields', errorFields);
  };

  return (
    <>
      <Form form={form} layout={'horizontal'} name={formName || 'advanced_search'} className='orders-search-form' onFinish={onFinish} onValuesChange={onValuesChange} onFinishFailed={onFinishFailed} >
        {/* <EditableContext.Provider value={form}> */}
        <Row gutter={16}>
          {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, 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' loading={loading}>
                {confirmText || t('Search')}
              </Button>
              {/* <Button size="small" onClick={onReset}>
                重置
              </Button> */}
            </Space>
          </Col>
        </Row>
        {/* </EditableContext.Provider> */}
      </Form>
    </>
  );
};

function getFields(props) {
  const { fieldProps, fieldComProps, 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(
      'keyword',
      99,
      <Form.Item name='keyword' {...fieldProps.keyword}>
        <Input allowClear {...fieldComProps.keyword} />
      </Form.Item>,
      fieldProps?.keyword?.col || 6
    ),
    item(
      'referenceNo',
      99,
      <Form.Item name='referenceNo' label={t('group:RefNo')} {...fieldProps.referenceNo}>
        <Input placeholder={t('group:RefNo')} allowClear />
      </Form.Item>,
      fieldProps?.referenceNo?.col || 6
    ),
    item(
      'PNR',
      99,
      <Form.Item name='PNR' label='PNR'>
        <Input placeholder={t('group:PNR')} allowClear />
      </Form.Item>,
      fieldProps?.PNR?.col || 4
    ),
    item(
      'invoiceStatus',
      99,
      <Form.Item name={`invoiceStatus`} initialValue={at(props, 'initialValue.invoiceStatus')[0] || { value: '0', label: 'Status' }}>
        <Select
          labelInValue
          options={[
            { value: '0', label: 'Status' },
            { value: '1', label: 'Not submitted' },
            { value: '2', label: 'Submitted' },
            { value: '3', label: 'Travel advisor approved' },
            { value: '4', label: 'Finance Dept arrproved' },
            { value: '5', label: 'Paid' },
          ]}
        />
      </Form.Item>,
      fieldProps?.invoiceStatus?.col || 3
    ),
    item(
      'dates',
      99,
      <Form.Item name={'dates'} label={t('group:ArrivalDate')} {...fieldProps.dates} initialValue={at(props, 'initialValue.dates')[0]}>
        {/* <DatePickerCharts isform={true} {...fieldProps.dates} form={form} /> */}
        <RangePicker allowClear={true} inputReadOnly={true} presets={presets} placeholder={['From', 'Thru']} {...fieldComProps.dates} />
      </Form.Item>,
      fieldProps?.dates?.col || midCol
    ),
    item(
      'username',
      99,
      <Form.Item name='username' label={t('account:username')} {...fieldProps.username}>
        <Input placeholder={t('account:username')} allowClear />
      </Form.Item>,
      fieldProps?.username?.col || 4
    ),
    item(
      'realname',
      99,
      <Form.Item name='realname' label={t('account:realname')} {...fieldProps.realname}>
        <Input placeholder={t('account:realname')} allowClear />
      </Form.Item>,
      fieldProps?.realname?.col || 4
    ),
    /**
     *
     */
    item(
      'year',
      99,
      <Form.Item name={'year'} label={t('products:UseYear')} {...fieldProps.year} initialValue={at(props, 'initialValue.year')[0]}>
        <DatePicker picker='year' allowClear {...fieldComProps.year} />
      </Form.Item>,
      fieldProps?.year?.col || 3
    ),
    item(
      'agency',
      99,
      <Form.Item name='agency' label={t('products:Vendor')} {...fieldProps.agency} initialValue={at(props, 'initialValue.agency')[0]}>
        <SearchInput
          placeholder={t('products:Vendor')}
          mode={'multiple'}
          maxTagCount={0}
          {...fieldComProps.agency}
          fetchOptions={fetchVendorList}
          map={{ travel_agency_name: 'label', travel_agency_id: 'value' }}
        />
      </Form.Item>,
      fieldProps?.agency?.col || 6
    ),
    item(
      'audit_state',
      99,
      <Form.Item name={`audit_state`} initialValue={at(props, 'initialValue.audit_state')[0] || { value: '', label: 'Status' }}>
        <AuditStateSelector {...fieldComProps.audit_state} />
      </Form.Item>,
      fieldProps?.audit_state?.col || 3
    ),
    item(
      'products_types',
      99,
      <Form.Item name={`products_types`} label={t('products:ProductType')}  {...fieldProps.products_types} initialValue={at(props, 'initialValue.products_types')[0] || undefined}>
        <SelectProductsTypes maxTagCount={1} {...fieldComProps.products_types} />
      </Form.Item>,
      fieldProps?.products_types?.col || 6
    ),
    item(
      'dept',
      99,
      <Form.Item name={`dept`} label={t('products:Dept')}  {...fieldProps.dept} initialValue={at(props, 'initialValue.dept')[0] || undefined}>
        <DeptSelector {...fieldComProps.dept} />
      </Form.Item>,
      fieldProps?.dept?.col || 6
    ),
    item(
      'unconfirmed',
      99,
      <Form.Item name={`unconfirmed`}  valuePropName='checked' initialValue={at(props, 'initialValue.unconfirmed') || false}>
        <Checkbox>{t('group:unconfirmed')}</Checkbox>
      </Form.Item>,
      fieldProps?.unconfirmed?.col || 2
    ),
  ];
  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;
