import { mdiCalendarCheck } 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 { SwitchField } from '../../components/SwitchField'
import { getPageTitle } from '../../config'
import { getRoleLaneFromUser } from '../../helpers/roleLanes'
import LayoutAuthenticated from '../../layouts/Authenticated'
import { fetch, update } from '../../stores/reservations/reservationsSlice'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'

const formatDateTimeLocal = (value) => (value ? dayjs(value).format('YYYY-MM-DDTHH:mm') : '')

const emptyValues = {
  tenant: null,
  organization: null,
  booking_request: null,
  reservation_code: '',
  status: 'quoted',
  property: null,
  unit: null,
  unit_type: null,
  check_in_at: '',
  check_out_at: '',
  actual_check_in_at: '',
  actual_check_out_at: '',
  early_check_in: false,
  late_check_out: false,
  guest_count: '',
  nightly_rate: '',
  monthly_rate: '',
  currency: 'USD',
  internal_notes: '',
  external_notes: '',
}

const buildInitialValues = (record) => ({
  tenant: record?.tenant || null,
  organization: record?.organization || null,
  booking_request: record?.booking_request || null,
  reservation_code: record?.reservation_code || '',
  status: record?.status || 'quoted',
  property: record?.property || null,
  unit: record?.unit || null,
  unit_type: record?.unit_type || null,
  check_in_at: formatDateTimeLocal(record?.check_in_at),
  check_out_at: formatDateTimeLocal(record?.check_out_at),
  actual_check_in_at: formatDateTimeLocal(record?.actual_check_in_at),
  actual_check_out_at: formatDateTimeLocal(record?.actual_check_out_at),
  early_check_in: Boolean(record?.early_check_in),
  late_check_out: Boolean(record?.late_check_out),
  guest_count: record?.guest_count ?? '',
  nightly_rate: record?.nightly_rate ?? '',
  monthly_rate: record?.monthly_rate ?? '',
  currency: record?.currency || 'USD',
  internal_notes: record?.internal_notes || '',
  external_notes: record?.external_notes || '',
})

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

  const roleLane = getRoleLaneFromUser(currentUser)
  const canManagePlatformFields = roleLane === 'super_admin'
  const canManageFinancialFields = canManagePlatformFields || roleLane === 'admin'
  const canManageOperations = roleLane !== 'customer'
  const pageTitle = roleLane === 'customer' ? 'My Stay' : 'Update Stay'
  const introCopy = canManagePlatformFields
    ? 'Update routing, internal references, housing assignment, and arrival execution details.'
    : canManageFinancialFields
      ? 'Keep the stay aligned across sourcing, housing, pricing, and arrival execution.'
      : 'Update operational stay details while system-managed routing stays protected.'

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

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

    return emptyValues
  }, [reservations])

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

    if (!canManagePlatformFields) {
      delete payload.tenant
      delete payload.organization
      delete payload.reservation_code
    }

    if (!canManageFinancialFields) {
      delete payload.nightly_rate
      delete payload.monthly_rate
      delete payload.internal_notes
    }

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

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

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

        <CardBox className='mx-auto max-w-6xl'>
          <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'>
                {canManagePlatformFields && (
                  <>
                    <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='Reservation code'>
                      <Field name='reservation_code' placeholder='Reservation code' />
                    </FormField>
                  </>
                )}

                <FormField label='Source request' labelFor='booking_request'>
                  <Field name='booking_request' id='booking_request' component={SelectField} options={initialValues.booking_request} itemRef={'booking_requests'} showField={'request_code'} />
                </FormField>

                <FormField label='Status' labelFor='status'>
                  <Field name='status' id='status' component='select'>
                    <option value='quoted'>quoted</option>
                    <option value='confirmed'>confirmed</option>
                    <option value='checked_in'>checked_in</option>
                    <option value='checked_out'>checked_out</option>
                    <option value='canceled'>canceled</option>
                    <option value='no_show'>no_show</option>
                  </Field>
                </FormField>

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

                <FormField label='Unit' labelFor='unit'>
                  <Field name='unit' id='unit' component={SelectField} options={initialValues.unit} itemRef={'units'} showField={'unit_number'} />
                </FormField>

                <FormField label='Unit type' labelFor='unit_type'>
                  <Field name='unit_type' id='unit_type' component={SelectField} options={initialValues.unit_type} itemRef={'unit_types'} showField={'name'} />
                </FormField>

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

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

                {canManageOperations && (
                  <>
                    <FormField label='Actual check-in'>
                      <Field type='datetime-local' name='actual_check_in_at' />
                    </FormField>

                    <FormField label='Actual check-out'>
                      <Field type='datetime-local' name='actual_check_out_at' />
                    </FormField>
                  </>
                )}

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

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

                {canManageFinancialFields && (
                  <>
                    <FormField label='Nightly rate'>
                      <Field type='number' min='0' step='0.01' name='nightly_rate' placeholder='Nightly rate' />
                    </FormField>

                    <FormField label='Monthly rate'>
                      <Field type='number' min='0' step='0.01' name='monthly_rate' placeholder='Monthly rate' />
                    </FormField>
                  </>
                )}

                <FormField label='Early check-in' labelFor='early_check_in'>
                  <Field name='early_check_in' id='early_check_in' component={SwitchField} />
                </FormField>

                <FormField label='Late check-out' labelFor='late_check_out'>
                  <Field name='late_check_out' id='late_check_out' component={SwitchField} />
                </FormField>

                <div className='md:col-span-2'>
                  <FormField label='Guest-facing notes' hasTextareaHeight>
                    <Field name='external_notes' as='textarea' placeholder='Arrival details, move-in notes, or traveler-facing instructions' />
                  </FormField>
                </div>

                {canManageFinancialFields && (
                  <div className='md:col-span-2'>
                    <FormField label='Internal notes' hasTextareaHeight>
                      <Field name='internal_notes' as='textarea' placeholder='Internal coordination, pricing context, or escalation notes' />
                    </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='button' color='danger' outline label='Cancel' onClick={() => router.push('/reservations/reservations-list')} />
              </BaseButtons>
            </Form>
          </Formik>
        </CardBox>
      </SectionMain>
    </>
  )
}

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

export default EditReservationsPage
