import { mdiCalendarCheck } from '@mdi/js'
import Head from 'next/head'
import { uniqueId } from 'lodash'
import React, { ReactElement, useMemo, useState } from 'react'
import axios from 'axios'

import BaseButton from '../../components/BaseButton'
import BaseButtons from '../../components/BaseButtons'
import CardBox from '../../components/CardBox'
import CardBoxModal from '../../components/CardBoxModal'
import DragDropFilePicker from '../../components/DragDropFilePicker'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import TableReservations from '../../components/Reservations/TableReservations'
import { getPageTitle } from '../../config'
import { buildNextFilterItem, filterEntityFieldsForRole, getAddFilterState, pruneHiddenFilterItems } from '../../helpers/entityVisibility'
import { humanize } from '../../helpers/humanize'
import { getRoleLaneFromUser } from '../../helpers/roleLanes'
import { hasPermission } from '../../helpers/userPermissions'
import LayoutAuthenticated from '../../layouts/Authenticated'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import { setRefetch, uploadCsv } from '../../stores/reservations/reservationsSlice'

const ReservationsTablesPage = () => {
  const [filterItems, setFilterItems] = useState([])
  const [csvFile, setCsvFile] = useState<File | null>(null)
  const [isModalActive, setIsModalActive] = useState(false)

  const { currentUser } = useAppSelector((state) => state.auth)
  const dispatch = useAppDispatch()

  const roleLane = getRoleLaneFromUser(currentUser)
  const canManagePlatformFields = roleLane === 'super_admin'
  const hasCreatePermission = currentUser && hasPermission(currentUser, 'CREATE_RESERVATIONS')
  const createButtonLabel = roleLane === 'concierge' ? 'Create stay' : 'New stay'
  const title = roleLane === 'customer' ? 'My Stays' : roleLane === 'concierge' ? 'Active Stays' : 'Stays'
  const subtitle = roleLane === 'customer'
    ? 'Track confirmed housing, arrivals, departures, and current stay details.'
    : 'A clean operating board for arrivals, departures, and stay execution.'

  const filters = useMemo(() => {
    const baseFilters = [
      { label: 'Reservationcode', title: 'reservation_code' },
      { label: 'Currency', title: 'currency' },
      { label: 'Externalnotes', title: 'external_notes' },
      { label: 'Guestcount', title: 'guest_count', number: 'true' },
      { label: 'Check-inat', title: 'check_in_at', date: 'true' },
      { label: 'Check-outat', title: 'check_out_at', date: 'true' },
      { label: 'Actualcheck-inat', title: 'actual_check_in_at', date: 'true' },
      { label: 'Actualcheck-outat', title: 'actual_check_out_at', date: 'true' },
      { label: 'Bookingrequest', title: 'booking_request' },
      { label: 'Property', title: 'property' },
      { label: 'Unit', title: 'unit' },
      { label: 'Unittype', title: 'unit_type' },
      { label: 'Guests', title: 'guests' },
      { label: 'Servicerequests', title: 'service_requests' },
      { label: 'Documents', title: 'documents' },
      { label: 'Status', title: 'status', type: 'enum', options: ['quoted', 'confirmed', 'checked_in', 'checked_out', 'canceled', 'no_show'] },
    ]

    if (canManagePlatformFields) {
      baseFilters.splice(8, 0, { label: 'Tenant', title: 'tenant' })
    }

    if (roleLane === 'admin' || roleLane === 'super_admin') {
      baseFilters.splice(3, 0, { label: 'Nightlyrate', title: 'nightly_rate', number: 'true' }, { label: 'Monthlyrate', title: 'monthly_rate', number: 'true' }, { label: 'Internalnotes', title: 'internal_notes' })
      baseFilters.push({ label: 'Invoices', title: 'invoices' })
    }

    return filterEntityFieldsForRole('reservations', roleLane, baseFilters).map((filter) => ({ ...filter, label: humanize(filter.title) }))
  }, [canManagePlatformFields, roleLane])

  React.useEffect(() => {
    setFilterItems((currentItems) => pruneHiddenFilterItems(currentItems, filters))
  }, [filters])

  const addFilterState = useMemo(() => getAddFilterState(filterItems, filters), [filterItems, filters])

  const addFilter = () => {
    setFilterItems((currentItems) => {
      const nextItem = buildNextFilterItem(currentItems, filters, () => uniqueId())

      return nextItem ? [...currentItems, nextItem] : currentItems
    })
  }

  const getReservationsCSV = async () => {
    const response = await axios({ url: '/reservations?filetype=csv', method: 'GET', responseType: 'blob' })
    const type = response.headers['content-type']
    const blob = new Blob([response.data], { type })
    const link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = 'reservationsCSV.csv'
    link.click()
  }

  const onModalConfirm = async () => {
    if (!csvFile) return
    await dispatch(uploadCsv(csvFile))
    dispatch(setRefetch(true))
    setCsvFile(null)
    setIsModalActive(false)
  }

  return (
    <>
      <Head>
        <title>{getPageTitle(title)}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiCalendarCheck} title={title} subtitle={subtitle} main />

        <CardBox className='mb-6 border border-white/10 shadow-none'>
          <div className='flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between'>
            <div>
              <p className='text-xs font-semibold uppercase tracking-[0.18em] text-slate-400'>Working view</p>
              <h2 className='mt-1 text-lg font-semibold text-white'>Stay calendar</h2>
              <p className='mt-1 text-sm text-slate-400'>Create, filter, export, and review stay execution from a single calm surface.</p>
            </div>

            <div className='flex w-full flex-col gap-3 xl:w-auto xl:items-end'>
              <BaseButtons
                type='justify-start xl:justify-end'
                mb='mb-0'
                classAddon='mb-2 mr-0 w-full sm:mr-2 sm:w-auto last:mr-0'
                className='w-full xl:w-auto'
              >
                {hasCreatePermission ? <BaseButton href='/reservations/reservations-new' color='info' label={createButtonLabel} /> : null}
                <BaseButton
                  color='whiteDark'
                  outline
                  label={addFilterState.buttonLabel}
                  onClick={addFilter}
                  disabled={!addFilterState.canAddFilter}
                />
                <BaseButton color='whiteDark' outline label='Export CSV' onClick={getReservationsCSV} />
                {hasCreatePermission ? <BaseButton color='whiteDark' outline label='Import CSV' onClick={() => setIsModalActive(true)} /> : null}
                <BaseButton href='/reservations/reservations-table' color='whiteDark' outline label='Table view' />
              </BaseButtons>

              <p className='max-w-full text-left text-xs leading-5 text-slate-400 xl:max-w-sm xl:text-right'>{addFilterState.helperText}</p>
            </div>
          </div>
        </CardBox>

        <CardBox className='mb-6' hasTable>
          <TableReservations filterItems={filterItems} setFilterItems={setFilterItems} filters={filters} />
        </CardBox>
      </SectionMain>

      <CardBoxModal title='Upload CSV' buttonColor='info' buttonLabel='Confirm' isActive={isModalActive} onConfirm={onModalConfirm} onCancel={() => setIsModalActive(false)}>
        <DragDropFilePicker file={csvFile} setFile={setCsvFile} formats={'.csv'} />
      </CardBoxModal>
    </>
  )
}

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

export default ReservationsTablesPage
