import { AdaptableCard } from '@/components/shared'
import Container from '@/components/shared/Container'
import {
  Button,
  Card,
  Checkbox,
  FormContainer,
  FormItem,
  Input,
  Menu,
  Select,
  Tooltip,
  toast,
} from '@/components/ui'
import Notification from '@/components/ui/Notification'
import { APP_NAME } from '@/constants/app.constant'
import { MainGroupedSettingDto } from '@/proxy/settings/models'
import { getList, updateSettingValues } from '@/services/setting-ui.service'
import { useStoreActions, useStoreState } from '@/store'
import { SelectBoxOption } from '@/types/shared'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
import isEmpty from 'lodash/isEmpty'
import { useEffect, useMemo, useState } from 'react'
import { Helmet } from 'react-helmet'
import { FaQuestionCircle } from 'react-icons/fa'

function getOptions(selectOptions?: Record<string, string>) {
  const options: SelectBoxOption[] = []

  if (!selectOptions) {
    return options
  }

  Object.entries(selectOptions).forEach(([key, value]) =>
    options.push({
      value: key,
      label: value,
    }),
  )

  return options
}

const Settings = () => {
  const { translate } = useLocalization()
  const [list, setList] = useState<MainGroupedSettingDto[]>([])
  const [mainGroups, setMainGroups] = useState<string[]>([])
  const [activeMainGroupKey, setActiveMainGroupKey] = useState<string>()
  const activeMainGroup = useMemo(
    () => list.find((a) => a.groupName === activeMainGroupKey),
    [activeMainGroupKey, list],
  )
  const { getConfig } = useStoreActions((a) => a.abpConfig)
  const { setMode } = useStoreActions((actions) => actions.theme)

  const onFormSubmit = async (
    values: Record<string, string>,
    setSubmitting: (isSubmitting: boolean) => void,
    activeGroupName?: string,
  ) => {
    //Dark Mode verildimi ?
    if (values.App_SiteManagement_Theme_Style) {
      setMode(
        values.App_SiteManagement_Theme_Style.includes('.dark') ? 'dark' : 'light',
      )
    }
    console.log(values)
    const resp = await updateSettingValues(values)
    if (resp.status === 204) {
      await fetchData(activeGroupName)
      toast.push(
        <Notification
          title={
            translate('::' + activeGroupName) +
            ' ' +
            translate('::SuccessfullySaved')
          }
          type="success"
        />,
        {
          placement: 'top-end',
        },
      )
    } else {
      toast.push(<Notification title={resp?.error?.message} type="danger" />, {
        placement: 'top-end',
      })
    }
    //getConfig değiştiriliyor.
    getConfig(false)
    setSubmitting(false)
  }

  const mode = useStoreState((state) => state.theme.mode)

  const fetchData = async (activeGroupName?: string) => {
    const result = await getList()

    if (result.data) {
      setList(result.data)
      if (activeGroupName) {
        setActiveMainGroupKey(activeGroupName)
      } else {
        setActiveMainGroupKey(result.data.length ? result.data[0].groupName : '')
      }
      setMainGroups(result.data.map((a) => a.groupName))
    }
  }

  useEffect(() => {
    if (isEmpty(list)) {
      fetchData()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return (
    <Container className="h-full">
      <Helmet
        titleTemplate={`%s | ${APP_NAME}`}
        title={translate('::' + 'App.Settings')}
        defaultTitle={APP_NAME}
      ></Helmet>

      <div className="flex flex-col md:flex-row gap-4">
        <div className="md:w-2/12 min-w-fit">
          <Menu className="p-2" variant={mode} defaultActiveKeys={[activeMainGroupKey ?? '']}>
            {mainGroups.map((group) => (
              <Menu.MenuItem
                key={group}
                className="break-all whitespace-normal"
                eventKey={group}
                onSelect={() => setActiveMainGroupKey(group)}
              >
                {translate('::' + group)}
              </Menu.MenuItem>
            ))}
          </Menu>
        </div>
        <div className="md:w-10/12 w-full">
          <AdaptableCard>
            {activeMainGroup?.subGroups.map((subGroup) => (
              <Card
                key={subGroup.subGroupName}
                className="mb-5 "
                header={translate('::' + subGroup.subGroupName)}
              >
                <Formik
                  initialValues={subGroup.settings.reduce((acc: any, cur) => {
                    if (!cur.code) {
                      return acc
                    }

                    if (cur.dataType === 'Bool') {
                      acc[cur.code] = cur.valueBool
                    } else {
                      acc[cur.code] = cur.value
                    }

                    return acc
                  }, {})}
                  onSubmit={(values, { setSubmitting }) => {
                    setSubmitting(true)
                    setTimeout(() => {
                      onFormSubmit(values, setSubmitting, activeMainGroupKey)
                    }, 1000)
                  }}
                >
                  {({ values, touched, errors, isSubmitting }) => (
                    <Form>
                      <FormContainer>
                        {subGroup.settings.map((setting) => (
                          <FormItem
                            key={setting.code}
                            label={translate('::' + setting.name) + ' (' + setting.providers?.replaceAll('|', ', ') + ')'}
                            extra={
                              <Tooltip title={translate('::' + setting.description)}>
                                <FaQuestionCircle className="text-lg cursor-pointer ml-1" />
                              </Tooltip>
                            }
                          >
                            <>
                              {setting.dataType === 'Text' && (
                                <Field type="text" name={setting.code} component={Input} />
                              )}
                              {setting.dataType === 'Number' && (
                                <Field type="number" name={setting.code} component={Input} />
                              )}
                              {setting.dataType === 'Memo' && (
                                <Field type="text" name={setting.code} textArea component={Input} />
                              )}
                              {setting.dataType === 'Bool' && (
                                <Field name={setting.code} component={Checkbox}></Field>
                              )}
                              {setting.dataType === 'List' && (
                                <Field name={setting.code}>
                                  {({ field, form }: FieldProps<any>) => (
                                    <Select
                                      field={field}
                                      form={form}
                                      options={getOptions(setting.selectOptions)}
                                      value={getOptions(setting.selectOptions).filter(
                                        (option) => option.value === values[setting.code],
                                      )}
                                      onChange={(option) =>
                                        form.setFieldValue(field.name, option?.value)
                                      }
                                    />
                                  )}
                                </Field>
                              )}
                            </>
                          </FormItem>
                        ))}
                        <FormItem>
                          <div className="float-right">
                            <Button
                              size="sm"
                              variant="solid"
                              className="ltr:mr-2 rtl:ml-2"
                              type="submit"
                              loading={isSubmitting}
                            >
                              {isSubmitting
                                ? translate('::SavingWithThreeDot')
                                : translate('::Save')}
                            </Button>
                          </div>
                        </FormItem>
                      </FormContainer>
                    </Form>
                  )}
                </Formik>
              </Card>
            ))}
          </AdaptableCard>
        </div>
      </div>
    </Container>
  )
}

export default Settings
