import { mdiChartTimelineVariant } from '@mdi/js'
import Head from 'next/head'
import React, { ReactElement, useEffect, useRef, useState } from 'react'
import { Field, Form, Formik, useFormikContext } from 'formik'
import { useRouter } from 'next/router'

import BaseButton from '../../components/BaseButton'
import BaseButtons from '../../components/BaseButtons'
import BaseDivider from '../../components/BaseDivider'
import CardBox from '../../components/CardBox'
import FormField from '../../components/FormField'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { SelectField } from '../../components/SelectField'
import { getPageTitle } from '../../config'
import { getRelationId } from '../../helpers/inventoryWorkspace'
import LayoutAuthenticated from '../../layouts/Authenticated'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import { fetch, update } from '../../stores/units/unitsSlice'

const emptyInitialValues = {
  id: '',
  property: null,
  unit_type: null,
  unit_number: '',
  floor: '',
  status: 'available',
  max_occupancy_override: '',
  notes: '',
}

const UnitPropertySync = () => {
  const { values, setFieldValue } = useFormikContext<any>()
  const previousPropertyRef = useRef(values.property)

  useEffect(() => {
    if (previousPropertyRef.current && previousPropertyRef.current !== values.property) {
      setFieldValue('unit_type', null)
    }

    previousPropertyRef.current = values.property
  }, [setFieldValue, values.property])

  return null
}

const EditUnitsPage = () => {
  const router = useRouter()
  const dispatch = useAppDispatch()
  const { units } = useAppSelector((state) => state.units)
  const [initialValues, setInitialValues] = useState(emptyInitialValues)
  const { id } = router.query

  useEffect(() => {
    if (!router.isReady || typeof id !== 'string') {
      return
    }

    dispatch(fetch({ id }))
  }, [dispatch, id, router.isReady])

  useEffect(() => {
    if (!units || Array.isArray(units) || typeof units !== 'object') {
      return
    }

    setInitialValues({
      ...emptyInitialValues,
      ...units,
    })
  }, [units])

  const handleSubmit = async (values: typeof emptyInitialValues) => {
    if (typeof id !== 'string') {
      return
    }

    await dispatch(update({ id, data: values }))
    await router.push('/units/units-list')
  }

  return (
    <>
      <Head>
        <title>{getPageTitle('Edit Unit')}</title>
      </Head>

      <SectionMain>
        <SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Edit Unit" main>
          {''}
        </SectionTitleLineWithButton>

        <CardBox className="mx-auto max-w-6xl">
          <Formik enableReinitialize initialValues={initialValues} onSubmit={handleSubmit}>
            {({ values }) => (
              <Form>
                <UnitPropertySync />

                <div className="mb-6 rounded-2xl border border-blue-200 bg-blue-50 px-4 py-4 text-sm text-blue-900 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-100">
                  Keep each unit tied to the right property and unit type. Availability blocks are handled later in the operating workflow, not here.
                </div>

                <div className="grid gap-5 md:grid-cols-2">
                  <FormField label="Property" labelFor="property" help="Choose where this unit belongs.">
                    <Field
                      name="property"
                      id="property"
                      component={SelectField}
                      options={initialValues.property}
                      itemRef={'properties'}
                      showField={'name'}
                      placeholder="Select a property"
                      noOptionsMessage="No properties available yet"
                    />
                  </FormField>

                  <FormField label="Unit type" labelFor="unit_type" help="Only unit types from the selected property are shown.">
                    <Field
                      name="unit_type"
                      id="unit_type"
                      component={SelectField}
                      options={initialValues.unit_type}
                      itemRef={'unit_types'}
                      showField={'name'}
                      queryParams={getRelationId(values.property) ? { property: getRelationId(values.property) } : undefined}
                      disabled={!getRelationId(values.property)}
                      placeholder={getRelationId(values.property) ? 'Select a unit type' : 'Select a property first'}
                      noOptionsMessage={
                        getRelationId(values.property) ? 'No unit types available for this property yet' : 'Select a property first'
                      }
                    />
                  </FormField>

                  <FormField label="Unit number" labelFor="unit_number">
                    <Field name="unit_number" id="unit_number" placeholder="1203" />
                  </FormField>

                  <FormField label="Floor" labelFor="floor">
                    <Field name="floor" id="floor" placeholder="12" />
                  </FormField>

                  <FormField label="Status" labelFor="status">
                    <Field name="status" id="status" component="select">
                      <option value="available">available</option>
                      <option value="occupied">occupied</option>
                      <option value="maintenance">maintenance</option>
                      <option value="cleaning_hold">cleaning_hold</option>
                      <option value="reserved">reserved</option>
                      <option value="out_of_service">out_of_service</option>
                    </Field>
                  </FormField>

                  <FormField label="Max occupancy override" labelFor="max_occupancy_override">
                    <Field type="number" name="max_occupancy_override" id="max_occupancy_override" placeholder="2" />
                  </FormField>

                  <div className="md:col-span-2">
                    <FormField label="Notes" labelFor="notes" hasTextareaHeight>
                      <Field name="notes" id="notes" as="textarea" placeholder="Operational notes" />
                    </FormField>
                  </div>
                </div>

                <BaseDivider />

                <BaseButtons>
                  <BaseButton type="submit" color="info" label="Save" />
                  <BaseButton type="reset" color="info" outline label="Reset" />
                  <BaseButton type="reset" color="danger" outline label="Cancel" onClick={() => router.push('/units/units-list')} />
                </BaseButtons>
              </Form>
            )}
          </Formik>
        </CardBox>
      </SectionMain>
    </>
  )
}

EditUnitsPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}

export default EditUnitsPage
