/* eslint-disable @typescript-eslint/no-explicit-any */
import { Box, CircularProgress, TextField } from '@mui/material'
import { LocalizationProvider, StaticDatePicker as DatePicker } from '@mui/x-date-pickers'
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'
import _get from 'lodash/get'
import _map from 'lodash/map'
import _sortBy from 'lodash/sortBy'
import moment from 'moment-timezone'
import React, { ReactNode, useMemo, useState } from 'react'

import { TimeSlotTicketRow } from './TimeSlotTicketRow'

interface Props {
  event: any;
  eventId: number;
  availableDates: string[];
  selectedDate: string | null;
  timeSlotGroups: { [key: string]: any[] };
  setTimeSlotGroups: (value: { [key: string]: any[] }) => void;
  setSelectedDate: (value: string | null) => void;
  getTimeSlots: (date: string | null, type?: string) => Promise<void>;

  selectedTickets: any;
  handleTicketSelect: any;
  sortBySoldOut: boolean;
  hideTicketsHeader: boolean;
  ticketsHeaderComponent?: ReactNode;
  showGroupNameBlock?: boolean;
  currencySymbol?: string;
  isSeatMapAllowed?: boolean;
}

interface TimeSlotOption {
  timeKey: string;
  ticketInstance: any;
}

interface UniqueTicket {
  ticket: any;
  availableTimeSlots: TimeSlotOption[];
}

const TimeSlotsSection: React.FC<Props> = ({
  event,
  availableDates,
  selectedDate,
  timeSlotGroups,
  setSelectedDate,
  getTimeSlots,
  selectedTickets,
  handleTicketSelect,
  sortBySoldOut,
  hideTicketsHeader,
  ticketsHeaderComponent,
  currencySymbol,
}) => {
  const [loading, setLoading] = useState(false)
  const [selectedTimeSlots, setSelectedTimeSlots] = useState<{ [key: string]: string }>({})

  const handleDateChange = async (date: string | null) => {
    setSelectedDate(date)
    setSelectedTimeSlots({}) // Reset time slot selections when date changes
    if (date) {
      setLoading(true)
      try {
        await getTimeSlots(date)
      } catch (error) {
        console.error('Error fetching time slots:', error)
      } finally {
        setLoading(false)
      }
    }
  }

  const isDateDisabled = (date: string) => {
    const formattedDate = moment(date).format('YYYY-MM-DD')
    return !availableDates.includes(formattedDate)
  }

  // Group tickets by unique ticket type using displayName + price
  const uniqueTickets = useMemo(() => {
    const ticketMap: { [key: string]: UniqueTicket } = {}

    // Iterate through all time slots
    _map(timeSlotGroups, (tickets, timeKey) => {
      tickets.forEach((ticket: any) => {
        // Use displayName + price as the unique identifier for ticket types
        // This handles cases where multiple ticket types share the same optionName
        const ticketKey = `${ticket.displayName || ticket.name}_${ticket.price}`

        if (!ticketMap[ticketKey]) {
          ticketMap[ticketKey] = {
            ticket: { ...ticket },
            availableTimeSlots: [],
          }
        }

        // Store both the time key and the ticket instance for this slot
        if (!ticketMap[ticketKey].availableTimeSlots.find((slot: any) => slot.timeKey === timeKey)) {
          ticketMap[ticketKey].availableTimeSlots.push({
            timeKey,
            ticketInstance: ticket,
          })
        }
      })
    })

    // Convert to array and sort
    const ticketsArray = Object.values(ticketMap)
    return sortBySoldOut
      ? _sortBy(_sortBy(ticketsArray, t => t.ticket.sortOrder), t => t.ticket.soldOut)
      : _sortBy(ticketsArray, t => t.ticket.sortOrder)
  }, [timeSlotGroups, sortBySoldOut])

  const handleTimeSlotSelect = (ticketKey: string, timeKey: string, ticketInstance: any) => {
    setSelectedTimeSlots(prev => ({
      ...prev,
      [ticketKey]: timeKey,
    }))

    // Reset quantity when time slot changes
    if (selectedTickets[ticketInstance.id]) {
      handleTicketSelect(ticketInstance.id, 0)
    }
  }

  const handleTicketSelectWithTimeSlot = (ticketKey: string, quantity: number, ticketInstance: any) => {
    const timeSlot = selectedTimeSlots[ticketKey]
    if (!timeSlot && quantity > 0) {
      return // Don't allow quantity selection without time slot
    }

    if (ticketInstance) {
      handleTicketSelect(ticketInstance.id, quantity)
    }
  }

  const symbol = _get(event, 'currency.symbol')
  const priceSymbol = currencySymbol || symbol

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <LocalizationProvider dateAdapter={AdapterMoment}>
        <DatePicker
          value={selectedDate}
          onChange={handleDateChange}
          shouldDisableDate={isDateDisabled}
          renderInput={params => <TextField {...params} />}
          showToolbar={false}
          componentsProps={{ actionBar: { actions: [] } }}
          disablePast
        />
      </LocalizationProvider>
      {loading ? (
        <CircularProgress sx={{ marginTop: 2 }} />
      ) : (
        <Box
          sx={{
            marginTop: 2,
            width: '100%',
            display: 'flex',
            flexDirection: 'column',
          }}
        >
          {!hideTicketsHeader && ticketsHeaderComponent}
          {uniqueTickets.map(({ ticket, availableTimeSlots }) => {
            const ticketKey = `${ticket.displayName || ticket.name}_${ticket.price}`
            const isSoldOut =
              ticket.sold_out ||
              !(ticket.displayTicket || ticket.slotGroupId) ||
              ticket.soldOut

            return (
              <TimeSlotTicketRow
                key={ticketKey}
                ticketKey={ticketKey}
                ticket={ticket}
                availableTimeSlots={availableTimeSlots}
                selectedTickets={selectedTickets}
                selectedTimeSlots={selectedTimeSlots}
                handleTicketSelect={handleTicketSelectWithTimeSlot}
                handleTimeSlotSelect={handleTimeSlotSelect}
                priceSymbol={priceSymbol}
                isSoldOut={isSoldOut}
              />
            )
          })}
        </Box>
      )}
    </Box>
  )
}

export default TimeSlotsSection
