import { CSSProperties } from '@emotion/serialize'
import { Select, SelectChangeEvent, ThemeOptions } from '@mui/material'
import CircularProgress from '@mui/material/CircularProgress'
import FormControl from '@mui/material/FormControl'
import InputLabel from '@mui/material/InputLabel'
import MenuItem from '@mui/material/MenuItem'
import { createTheme, ThemeProvider } from '@mui/material/styles'
import Tooltip from '@mui/material/Tooltip'
import _find from 'lodash/find'
import _identity from 'lodash/identity'
import _isEmpty from 'lodash/isEmpty'
import _keys from 'lodash/keys'
import _map from 'lodash/map'
import _some from 'lodash/some'
import React, { useState } from 'react'
import { Button } from 'react-bootstrap'

import { createFixedFloatNormalizer } from '../../normalizers'
import { createMarkup } from '../../utils'
import { getButtonLabel, getTicketDropdownData } from './utils'

export const TicketsSection = (
  props: ITicketsSectionProps & {
    themeOptions?: ThemeOptions & {
      input?: CSSProperties;
      checkbox?: CSSProperties;
    };
  }
) => {
  const {
    ticketTypeTierRelations,
    reservedSeats,
    theme = 'light',
    getTicketsBtnLabel,
    contentStyle = {},
    isButtonScrollable = false,
    themeOptions,
    handleGetTicketClick,
    handleCancelReservation,
    ticketDeleteButtonContent = 'Delete',
    ticketInfoContent = 'Info',
    selectedTickets,
    handleTicketSelect,
    currencySymbol,
    tableMapEnabled = false,
    guestCounts,
    setGuestCounts,
    isAddingToCart,
  } = props

  const [selectedTicketsInfo, setSelectedTicketsInfo] = useState<{
    [seatId: string]: boolean | undefined;
  }>({})

  const bookButtonIsDisabled =
    _some(selectedTickets, item => !item) ||
    _isEmpty(reservedSeats) ||
    reservedSeats.length !== _keys(selectedTickets).length
  const themeMui = createTheme(themeOptions)

  const ticketsDropdownsData = getTicketDropdownData(
    reservedSeats,
    ticketTypeTierRelations
  )

  const handleTicketChange = (event: SelectChangeEvent<string>, seatId: string) => {
    const {
      target: { value },
    } = event

    if (value !== 'default') {
      handleTicketSelect(value, seatId)
    }
  }

  const handleShowtTicketInfo = (seatId: string) => {
    setSelectedTicketsInfo(prevState => ({ ...prevState, [seatId]: !prevState[seatId] }))
  }

  return (
    <ThemeProvider theme={themeMui}>
      <div className={`get-tickets-page ${theme}`} style={contentStyle}>
        <div className="tickets-section">
          {_map(selectedTickets, (ticketItem: string, key: string) => {
            const dropdownData =
              _find(ticketsDropdownsData, item => item.seatId === key) ||
              ({} as ITicketsDropdownsData)

            const selectedTicketData = _find(
              dropdownData.ticketsData,
              ticket => ticket.ticket_type_id === ticketItem
            ) as TicketTypeTierRelationsData

            // guest count dropdown options
            const startNum = Number(selectedTicketData?.ticket_type_min_number_of_guests)
            const endNum = Number(selectedTicketData?.ticket_type_max_number_of_guests)
            const numLength = endNum - startNum + 1
            const showGuestCountDropdown = Boolean(startNum && endNum)
            const showDescription = Boolean(selectedTicketData?.description)

            // prices
            const guestPrice =
              (guestCounts[dropdownData.seatId] - startNum) *
              Number(selectedTicketData?.guest_price)

            const finalPrice = createFixedFloatNormalizer(2)(
              selectedTicketData?.ticket_type_price + guestPrice
            )

            return (
              <div className="ticket" key={key}>
                <div className="ticketsDropdowns">
                  <Select
                    value={ticketItem || 'default'}
                    onChange={event => handleTicketChange(event, dropdownData.seatId)}
                    inputProps={{ 'aria-label': 'Without label' }}
                    MenuProps={{
                      PaperProps: {
                        sx: { maxHeight: 150 },
                        className: 'get-tickets-paper',
                      },
                    }}
                    displayEmpty
                    sx={{ borderRadius: 0 }}
                  >
                    <MenuItem value={'default'}>
                      {`Please select ${tableMapEnabled ? 'Table Type' : 'Ticket Type'}`}
                    </MenuItem>
                    {_map(dropdownData.ticketsData, (option, index) => {
                      if (option.ticket_type_id !== 'default') {
                        return (
                          <MenuItem value={option.ticket_type_id} key={index}>
                            {option.ticket_type_name}
                          </MenuItem>
                        )
                      }
                      return null
                    })}
                  </Select>
                  <Button
                    className="ticket-delete"
                    onClick={() => {
                      handleCancelReservation(dropdownData.seatId, dropdownData.tierId)
                    }}
                  >
                    {ticketDeleteButtonContent}
                  </Button>
                </div>
                {selectedTicketData && (
                  <>
                    <div style={{ display: 'flex' }}>
                      <div
                        style={{
                          width: '100%',
                          display: 'flex',
                          flexDirection: 'column',
                          justifyContent: 'center',
                        }}
                      >
                        <div className="ticketPrice">
                          Price:
                          <span className="ticketPrice-value">
                            {`${currencySymbol} ${finalPrice}`}
                          </span>
                          <span className="fees">
                            {selectedTicketData.fee_included
                              ? ' (incl. Fees)'
                              : ' (excl. Fees)'}
                          </span>
                        </div>
                        {!_isEmpty(selectedTicketData.ticket_type_deposit) && (
                          <div className="ticketDeposit">
                            Deposit:
                            <span className="ticketPrice-value">
                              {` ${selectedTicketData?.ticket_type_deposit}%`}
                            </span>
                          </div>
                        )}
                      </div>
                      <div
                        style={{
                          width: '100%',
                          display: 'flex',
                          justifyContent: 'end',
                          alignItems: 'center',
                          marginRight: 16,
                        }}
                      >
                        {showDescription && (
                          <Tooltip
                            title="View Ticket Info"
                            placement="left"
                            arrow
                            componentsProps={{
                              tooltip: {
                                sx: {
                                  backgroundColor: 'common.black',
                                  marginRight: '6px !important',
                                  '& .MuiTooltip-arrow': {
                                    color: 'common.black',
                                  },
                                },
                              },
                            }}
                          >
                            <div
                              className="ticket-info"
                              onClick={() => handleShowtTicketInfo(dropdownData.seatId)}
                              onKeyDown={() => handleShowtTicketInfo(dropdownData.seatId)}
                            >
                              {ticketInfoContent}
                            </div>
                          </Tooltip>
                        )}
                        {showGuestCountDropdown && (
                          <FormControl variant="outlined" sx={{ m: 1, minWidth: 80 }}>
                            <InputLabel id="demo-simple-select-standard-label" shrink>
                              GUESTS
                            </InputLabel>
                            <Select
                              label="GUESTS"
                              labelId="demo-simple-select-standard-label"
                              value={guestCounts[dropdownData.seatId] || startNum}
                              onChange={event => {
                                setGuestCounts({
                                  ...guestCounts,
                                  [dropdownData.seatId]: Number(event.target.value),
                                })
                              }}
                              inputProps={{ 'aria-label': 'Without label' }}
                              MenuProps={{
                                PaperProps: {
                                  sx: { maxHeight: 150 },
                                  className: 'get-tickets-paper',
                                },
                              }}
                              displayEmpty
                              sx={{ borderRadius: 0 }}
                            >
                              {_map(
                                Array.from({ length: numLength }, (_, i) => startNum + i),
                                (option, index) => (
                                  <MenuItem value={option} key={index}>
                                    {option}
                                  </MenuItem>
                                )
                              )}
                            </Select>
                          </FormControl>
                        )}
                      </div>
                    </div>
                    {selectedTicketsInfo[dropdownData.seatId] && (
                      <div
                        className="ticket-description-content"
                        dangerouslySetInnerHTML={createMarkup(
                          selectedTicketData.description || ''
                        )}
                      />
                    )}
                  </>
                )}
              </div>
            )
          })}
        </div>
        <div>
          <Button
            className={`book-button
              ${bookButtonIsDisabled ? 'disabled' : ''}
              ${isButtonScrollable ? 'is-scrollable' : ''}
            `}
            onClick={!bookButtonIsDisabled ? handleGetTicketClick : _identity}
            disabled={isAddingToCart}
          >
            {isAddingToCart ? (
              <CircularProgress size={20} style={{ marginLeft: 10 }} />
            ) : (
              getTicketsBtnLabel || getButtonLabel(reservedSeats.length, tableMapEnabled)
            )}
          </Button>
        </div>
      </div>
    </ThemeProvider>
  )
}
