import { mdiChartTimelineVariant } from '@mdi/js'
import dayjs from 'dayjs'
import Head from 'next/head'
import React, { ReactElement, useEffect, useMemo } from 'react'
import { Field, Form, Formik } 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 LayoutAuthenticated from '../../layouts/Authenticated'
import { fetch, update } from '../../stores/booking_requests/booking_requestsSlice'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'

const emptyValues = {
  tenant: null,
  organization: null,
  requested_by: null,
  request_code: '',
  status: 'submitted',
  check_in_at: '',
  check_out_at: '',
  preferred_property: null,
  preferred_unit_type: null,
  preferred_bedrooms: '',
  guest_count: '',
  purpose_of_stay: '',
  special_requirements: '',
  budget_code: '',
  max_budget_amount: '',
  currency: 'USD',
}

const formatDateTimeLocal = (value) => {
  if (!value) {
    return ''
  }

  return dayjs(value).format('YYYY-MM-DDTHH:mm')
}

const buildInitialValues = (record) => ({
  tenant: record?.tenant || null,
  organization: record?.organization || null,
  requested_by: record?.requested_by || null,
  request_code: record?.request_code || '',
  status: record?.status || 'submitted',
  check_in_at: formatDateTimeLocal(record?.check_in_at),
  check_out_at: formatDateTimeLocal(record?.check_out_at),
  preferred_property: record?.preferred_property || null,
  preferred_unit_type: record?.preferred_unit_type || null,
  preferred_bedrooms: record?.preferred_bedrooms ?? '',
  guest_count: record?.guest_count ?? '',
  purpose_of_stay: record?.purpose_of_stay || '',
  special_requirements: record?.special_requirements || '',
  budget_code: record?.budget_code || '',
  max_budget_amount: record?.max_budget_amount ?? '',
  currency: record?.currency || 'USD',
})

const EditBooking_requestsPage = () => {
  const router = useRouter()
  const dispatch = useAppDispatch()
  const { currentUser } = useAppSelector((state) => state.auth)
  const { booking_requests, loading } = useAppSelector((state) => state.booking_requests)
  const { id } = router.query

  const canManageInternalFields = Boolean(currentUser?.app_role?.globalAccess)
  const pageTitle = canManageInternalFields ? 'Edit Booking Request' : 'Update Stay Request'
  const introCopy = canManageInternalFields
    ? 'Update the booking request and, if needed, adjust internal routing fields.'
    : 'Update the stay details. Internal ownership, organization routing, and the workflow reference stay system-managed.'

  useEffect(() => {
    if (id) {
      dispatch(fetch({ id }))
    }
  }, [dispatch, id])

  const initialValues = useMemo(() => {
    if (booking_requests && typeof booking_requests === 'object' && !Array.isArray(booking_requests)) {
      return buildInitialValues(booking_requests)
    }

    return emptyValues
  }, [booking_requests])

  const handleSubmit = async (values) => {
    const payload = { ...values }

    if (!canManageInternalFields) {
      delete payload.tenant
      delete payload.organization
      delete payload.requested_by
      delete payload.request_code
      delete payload.status
    }

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

  return (
    <>
      <Head>
        <title>{getPageTitle(pageTitle)}</title>
      </Head>

      <SectionMain>
        <SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={pageTitle} main>
          {''}
        </SectionTitleLineWithButton>

        <CardBox className='mx-auto max-w-5xl'>
          <div className='mb-6 rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4 text-sm text-slate-600 dark:border-white/10 dark:bg-slate-900/40 dark:text-slate-300'>
            {introCopy}
          </div>

          <Formik enableReinitialize initialValues={initialValues} onSubmit={handleSubmit}>
            <Form>
              <div className='grid gap-5 md:grid-cols-2'>
                {canManageInternalFields && (
                  <>
                    <FormField label='Tenant' labelFor='tenant'>
                      <Field name='tenant' id='tenant' component={SelectField} options={initialValues.tenant} itemRef={'tenants'} />
                    </FormField>

                    <FormField label='Organization' labelFor='organization'>
                      <Field name='organization' id='organization' component={SelectField} options={initialValues.organization} itemRef={'organizations'} />
                    </FormField>

                    <FormField label='Requested by' labelFor='requested_by'>
                      <Field name='requested_by' id='requested_by' component={SelectField} options={initialValues.requested_by} itemRef={'users'} />
                    </FormField>

                    <FormField label='Request code'>
                      <Field name='request_code' placeholder='Request code' />
                    </FormField>

                    <FormField label='Status' labelFor='status'>
                      <Field name='status' id='status' component='select'>
                        <option value='draft'>draft</option>
                        <option value='submitted'>submitted</option>
                        <option value='in_review'>in_review</option>
                        <option value='changes_requested'>changes_requested</option>
                        <option value='approved'>approved</option>
                        <option value='rejected'>rejected</option>
                        <option value='expired'>expired</option>
                        <option value='converted_to_reservation'>converted_to_reservation</option>
                        <option value='canceled'>canceled</option>
                      </Field>
                    </FormField>
                  </>
                )}

                <FormField label='Check-in' labelFor='check_in_at'>
                  <Field type='datetime-local' name='check_in_at' id='check_in_at' />
                </FormField>

                <FormField label='Check-out' labelFor='check_out_at'>
                  <Field type='datetime-local' name='check_out_at' id='check_out_at' />
                </FormField>

                <FormField label='Preferred property' labelFor='preferred_property'>
                  <Field name='preferred_property' id='preferred_property' component={SelectField} options={initialValues.preferred_property} itemRef={'properties'} />
                </FormField>

                <FormField label='Preferred unit type' labelFor='preferred_unit_type'>
                  <Field name='preferred_unit_type' id='preferred_unit_type' component={SelectField} options={initialValues.preferred_unit_type} itemRef={'unit_types'} />
                </FormField>

                <FormField label='Preferred bedrooms'>
                  <Field type='number' name='preferred_bedrooms' placeholder='Preferred bedrooms' min='0' />
                </FormField>

                <FormField label='Guest count'>
                  <Field type='number' name='guest_count' placeholder='Guest count' min='1' />
                </FormField>

                <FormField label='Budget code'>
                  <Field name='budget_code' placeholder='Budget code' />
                </FormField>

                <FormField label='Maximum budget amount'>
                  <Field type='number' name='max_budget_amount' placeholder='Maximum budget amount' min='0' step='0.01' />
                </FormField>

                <FormField label='Currency'>
                  <Field name='currency' placeholder='Currency' />
                </FormField>

                <div className='md:col-span-2'>
                  <FormField label='Purpose of stay' hasTextareaHeight>
                    <Field name='purpose_of_stay' as='textarea' placeholder='Describe the purpose of the stay' />
                  </FormField>
                </div>

                <div className='md:col-span-2'>
                  <FormField label='Special requirements' hasTextareaHeight>
                    <Field name='special_requirements' as='textarea' placeholder='Add guest, accessibility, or arrival details' />
                  </FormField>
                </div>
              </div>

              <BaseDivider />

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

EditBooking_requestsPage.getLayout = function getLayout(page: ReactElement) {
  return (
    <LayoutAuthenticated permission={'UPDATE_BOOKING_REQUESTS'}>
      {page}
    </LayoutAuthenticated>
  )
}

export default EditBooking_requestsPage
