import { useStyle } from './style.ts'
import { Badge, Button, Divider, Form, Popconfirm, Space, Tooltip } from 'antd'
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import { ModelContext, useSpanModel } from '@/store/r-form/model.ts'
import { ReactNode, useEffect, useState } from 'react'
import { transformAntdTableProColumns } from './utils'
import Action from '@/components/action/Action.tsx'
import { FilterOutlined } from '@ant-design/icons'
import ListPageLayout from '@/layout/ListPageLayout.tsx'
import { Table as ProTable } from '@/components/table'
import { getValueCount, unSetColumnRules } from '@/utils'
import { BetaSchemaForm, ProColumns, ProFormColumnsType } from '@ant-design/pro-components'
import { useApiContext } from '@/context.ts'
import { useDeepCompareEffect } from 'react-use'
import { RFormTypes } from '@/types/r-form/model'
import { ProCoreActionType } from '@ant-design/pro-utils/es/typing'
import { getI18nTitle } from '@/i18n.ts'


export interface RFormProps {
  title?: ReactNode
  namespace?: string
  columns?: ProColumns[] //重写columns
  actions?: ReactNode[] | JSX.Element[]  //左上角的操作按钮

  toolbar?: ReactNode   //工具栏
  renderActions?: (addAction: ReactNode) => ReactNode //渲染操作按钮
  resolveColumns?: (columns: ProColumns[]) => ProColumns[]  //处理columns
  renderColumnOptions?: (record: any, defaultOptions: ReactNode[], index: number, action: ProCoreActionType | undefined) => ReactNode //渲染列的操作
}

const RForm = (
        {
          namespace,
          actions = [],
          toolbar,
          resolveColumns,
          renderActions,
          renderColumnOptions,
          columns: propColumns = [], title
        }: RFormProps) => {

  const { styles, cx } = useStyle()
  const apiCtx = useApiContext()
  const {
    apiAtom,
    deleteModelAtom,
    modelAtom,
    modelCURDAtom,
    modelsAtom,
    modelSearchAtom,
    saveOrUpdateModelAtom
  } = useSpanModel(namespace || apiCtx?.menu?.meta?.name || 'default') as ModelContext
  const [ form ] = Form.useForm()
  const [ filterForm ] = Form.useForm()
  const setApi = useSetAtom(apiAtom)
  const [ model, setModel ] = useAtom<RFormTypes.IModel>(modelAtom)
  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateModelAtom)
  const [ search, setSearch ] = useAtom(modelSearchAtom)
  const { data, isFetching, isLoading, refetch } = useAtomValue(modelsAtom)
  const { mutate: deleteModel, isPending: isDeleting } = useAtomValue(deleteModelAtom)
  const { data: curdModal, isLoading: curdLoading, refetch: reloadCURDModal } = useAtomValue(modelCURDAtom)
  const [ open, setOpen ] = useState(false)
  const [ openFilter, setFilterOpen ] = useState(false)
  const [ searchKey, setSearchKey ] = useState(search?.key)
  const [ columns, setColumns ] = useState<ProColumns[]>([])

  useDeepCompareEffect(() => {

    let res = transformAntdTableProColumns(curdModal?.columns || [], propColumns, curdModal?.config?.i18n)
    if (resolveColumns) {
      res = resolveColumns(res)
    }

    const options = (record: any) => {
      return [
        <Action key="edit"
                as={'a'}
                onClick={() => {
                  form.setFieldsValue(record)
                  setOpen(true)
                }}>{'编辑'}</Action>,
        <Popconfirm
                key={'del_confirm'}
                disabled={isDeleting}
                onConfirm={() => {
                  deleteModel([ record.id ])
                }}
                title={'确定要删除吗?'}>
          <a key="del">
            删除
          </a>
        </Popconfirm>
      ]
    }

    const _columns = [ {
      title: 'ID',
      dataIndex: 'id',
      hideInTable: true,
      hideInSearch: true,
      formItemProps: { hidden: true }
    } ].concat(res as any).concat([
      {
        title: getI18nTitle(curdModal?.config?.i18n, { dataIndex: 'option', title: '操作' },),
        dataIndex: 'option',
        valueType: 'option',
        fixed: 'right',
        render: (_, record, index, action) => {
          if (renderColumnOptions) {
            return renderColumnOptions(record, options(record), index, action)
          }
          return options(record)
        }
      } as any
    ])
    setColumns(_columns)
  }, [ curdModal?.columns, curdModal?.config?.i18n, propColumns, renderColumnOptions, resolveColumns, deleteModel, form, isDeleting, setOpen, ])

  useEffect(() => {
    if (apiCtx.isApi && apiCtx.api) {
      setApi(apiCtx.api)
      reloadCURDModal()
    }
  }, [ apiCtx.isApi, apiCtx.api ])

  useDeepCompareEffect(() => {

    setSearchKey(search?.key)

    filterForm.setFieldsValue(search)

  }, [ search ])

  useEffect(() => {
    if (isSuccess) {
      setOpen(false)
    }
  }, [ isSuccess ])

  const formProps = curdModal?.form.layoutType === 'DrawerForm' ? {
    layoutType: 'DrawerForm',
    drawerProps: {
      maskClosable: false,
    }
  } : {
    layoutType: 'ModalForm',
    modalProps: {
      maskClosable: false,
    }
  }

  const renderTitle = () => {
    if (title) {
      return title
    }

    if (apiCtx.menu) {
      const { menu } = apiCtx
      return menu.title
    }
    return null
  }

  const tableTitle = <>
    <Button key={'add'}
            onClick={() => {
              form.resetFields()
              form.setFieldsValue({
                id: 0,
              })
              setOpen(true)
            }}
            type={'primary'}>{getI18nTitle('actions.add','添加')}</Button>
  </>

  const _renderActions = () => {
    if (renderActions) {
      return renderActions(tableTitle)
    }
    return <Space>
      {[ tableTitle, ...actions ]}
    </Space>
  }

  return (
          <>
            <ListPageLayout
                    className={styles.container}
                    title={renderTitle()}>

              <ProTable
                      {...curdModal?.table}
                      rowKey="id"
                      headerTitle={_renderActions()}
                      toolbar={{
                        /*search: {
                          loading: isFetching && !!search?.key,
                          onSearch: (value: string) => {
                            setSearch(prev => ({
                              ...prev,
                              title: value
                            }))
                          },
                          allowClear: true,
                          onChange: (e) => {
                            setSearchKey(e.target?.value)
                          },
                          value: searchKey,
                          placeholder: '输入关键字搜索',
                        },*/
                        actions: [
                          <Tooltip key={'filter'} title={getI18nTitle('actions.advanceSearch','高级查询')}>
                            <Badge count={getValueCount(search)}>
                              <Button
                                      onClick={() => {
                                        setFilterOpen(true)
                                      }}
                                      icon={<FilterOutlined/>} shape={'circle'} size={'small'}/>
                            </Badge>
                          </Tooltip>,
                          <Divider type={'vertical'} key={'divider'}/>,

                        ]
                      }}
                      scroll={{
                        x: (columns?.length || 1) * 100,
                        y: 'calc(100vh - 290px)'
                      }}
                      search={false}
                      onRow={(record) => {
                        return {
                          className: cx({
                            // 'ant-table-row-selected': currentMovie?.id === record.id
                          }),
                          onClick: () => {
                            setModel(record)
                          }
                        }
                      }}
                      dateFormatter="string"
                      loading={isLoading || isFetching || curdLoading}
                      dataSource={data?.rows ?? []}
                      columns={columns}
                      options={{
                        reload: () => {
                          refetch()
                        },
                      }}
                      pagination={{
                        total: data?.total,
                        pageSize: search.pageSize,
                        current: search.page,
                        onShowSizeChange: (current: number, size: number) => {
                          setSearch({
                            ...search,
                            pageSize: size,
                            page: current
                          })
                        },
                        onChange: (current, pageSize) => {
                          setSearch(prev => {
                            return {
                              ...prev,
                              page: current,
                              pageSize: pageSize,
                            }
                          })
                        },
                      }}
              />

              <BetaSchemaForm
                      {...curdModal?.form}
                      grid={true}
                      shouldUpdate={false}
                      width={1000}
                      form={form}
                      layout={'vertical'}
                      scrollToFirstError={true}
                      title={model?.id !== 0 ? getI18nTitle('actions.edit','编辑') : getI18nTitle('actions.add','添加')}
                      {...formProps as any}
                      open={open}
                      onOpenChange={(open) => {
                        setOpen(open)
                      }}
                      loading={isSubmitting}
                      onFinish={async (values) => {
                        console.log(values)
                        saveOrUpdate(values as any)
                      }}
                      columns={columns as ProFormColumnsType[]}/>
              <BetaSchemaForm
                      {...curdModal?.form}
                      title={getI18nTitle('actions.advanceSearch','高级查询')}
                      grid={true}
                      shouldUpdate={false}
                      width={500}
                      form={filterForm}
                      open={openFilter}
                      onOpenChange={open => {
                        setFilterOpen(open)
                      }}
                      layout={'vertical'}
                      scrollToFirstError={true}
                      layoutType={formProps.layoutType as any}
                      drawerProps={{
                        ...formProps.drawerProps,
                        mask: false,
                      }}
                      modalProps={{
                        ...formProps.modalProps,
                        mask: false,
                      }}
                      submitter={{
                        searchConfig: {
                          resetText: getI18nTitle('actions.clear', '清空'),
                          submitText: getI18nTitle('actions.search', '查询'),
                        },
                        onReset: () => {
                          filterForm.resetFields()
                        },
                        render: (props,) => {
                          return (
                                  <div style={{ textAlign: 'right' }}>
                                    <Space>
                                      <Button onClick={() => {
                                        props.reset()

                                      }}>{props.searchConfig?.resetText}</Button>
                                      <Button type="primary"
                                              onClick={() => {
                                                props.submit()
                                              }}
                                      >{props.searchConfig?.submitText}</Button>
                                    </Space>
                                  </div>
                          )
                        },

                      }}


                      onFinish={async (values: any) => {
                        //处理,变成数组
                        Object.keys(values).forEach(key => {
                          if (typeof values[key] === 'string' && values[key].includes(',')) {
                            values[key] = values[key].split(',')
                          }
                        })

                        setSearch(values)

                      }}
                      columns={unSetColumnRules(columns.filter(item => !item.hideInSearch) as ProFormColumnsType[])}/>

            </ListPageLayout>
          </>
  )
}

export default RForm