/* eslint-disable @typescript-eslint/no-explicit-any */
import './style.css'

import _get from 'lodash/get'
import _sortBy from 'lodash/sortBy'
import React, { ReactNode, useState } from 'react'
import { Tooltip } from 'react-tooltip'

import { FEES_STYLES } from '../../constants'
import { CONFIGS } from '../../utils'
import InfoIcon from './InfoIcon'
import { TicketRow } from './TicketRow'

function decodeHTML(html: string): string {
  const textArea = document.createElement('textarea')
  textArea.innerHTML = html
  return textArea.value
}

interface ITicketsSectionProps {
  event: any;
  ticketsList: any;
  selectedTickets: any;
  handleTicketSelect: any;
  sortBySoldOut: boolean;
  hideTicketsHeader: boolean;
  hideTableTicketsHeader: boolean;
  tableTickets: any;
  ticketsHeaderComponent?: ReactNode;
  tableTicketsHeaderComponent?: ReactNode;
  showGroupNameBlock?: boolean;
  currencySymbol?: string;
  isSeatMapAllowed?: boolean;
  descriptionTrigger?: 'click' | 'hover';
}

export const TicketsSection = ({
  event,
  ticketsList,
  selectedTickets,
  handleTicketSelect,
  sortBySoldOut,
  ticketsHeaderComponent,
  tableTicketsHeaderComponent,
  hideTicketsHeader,
  hideTableTicketsHeader,
  showGroupNameBlock,
  currencySymbol,
  isSeatMapAllowed,
  tableTickets,
  descriptionTrigger = 'click',
}: ITicketsSectionProps) => {
  const symbol = _get(event, 'currency.symbol')
  const sortedTicketsList = sortBySoldOut
    ? _sortBy(_sortBy(ticketsList, 'sortOrder'), 'soldOut')
    : _sortBy(ticketsList, 'sortOrder')
  const showGroup = !!sortedTicketsList.find(ticket => ticket.groupName)
  const priceSymbol = currencySymbol || symbol

  const [visibleDescription, setVisibleDescription] = useState<string | null>(null)

  const handleDescriptionToggle = (ticketId: string) => {
    setVisibleDescription(current => (current === ticketId ? null : ticketId))
  }

  return (
    <>
      {!hideTicketsHeader && ticketsHeaderComponent}
      {sortedTicketsList.map((ticket, i, arr) => {
        const ticketPriceWithoutFees = `${priceSymbol} ${(+ticket.cost).toFixed(2)}`
        const ticketPriceWithFees = `${priceSymbol} ${(+ticket.basePrice).toFixed(2)}`
        const ticketOldPriceWithFees = `${priceSymbol} ${(+ticket.oldBasePrice).toFixed(2)}`
        const ticketOldPriceWithoutFees = `${priceSymbol} ${(+ticket.oldCost).toFixed(2)}`
        const ticketFinalPrice = ticket.feeIncluded && !ticket.isForward
          ? +(ticket.x_face_value || ticket.basePrice)
          : ticket.feeIncluded ? +ticket.basePrice : +ticket.cost
        const ticketFinalPriceFormatted = `${priceSymbol} ${parseFloat(ticketFinalPrice.toFixed(2))}`
        const ticketOldFinalPrice = ticket.feeIncluded && !ticket.isForward
          ? +(ticket.x_face_value || ticket.basePrice)
          : ticket.feeIncluded ? +ticket.oldBasePrice : +ticket.oldCost
        const ticketOldFinalPriceFormatted = `${priceSymbol} ${parseFloat(ticketOldFinalPrice.toFixed(2))}`
        const ticketFeeAmount = (+ticket.basePrice - +ticket.cost).toFixed(2)
        const ticketBreakdown = !ticket.feeIncluded
          ? '(+ fees at checkout)'
          : !ticket.isForward
            ? null
            : (parseFloat(ticketFeeAmount) > 0 ? `(${priceSymbol} ${(+ticket.cost).toFixed(2)} + ${priceSymbol} ${ticketFeeAmount} fee)` : null)

        const isSoldOut =
          ticket.sold_out ||
          !(ticket.displayTicket || ticket.slotGroupId) ||
          ticket.soldOut
        const ticketSelect = (event: any) => {
          const { value } = event.target
          handleTicketSelect(ticket.id, value)
        }

        let ticketIsDiscounted = false
        if (ticket.oldPrice && !isSoldOut && ticket.oldPrice !== ticket.price) {
          ticketIsDiscounted = true
        }

        const ticketIsFree = +ticket.price === 0
        const discountTicketPriceElem = CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN
          ? ticketOldFinalPriceFormatted
          : CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded
            ? ticketOldPriceWithoutFees
            : ticketOldPriceWithFees
        const ticketPriceElem = isSoldOut
          ? 'SOLD OUT'
          : ticketIsFree
            ? 'FREE'
            : CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN
              ? ticketFinalPriceFormatted
              : (CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded)
                ? ticketPriceWithoutFees
                : ticketPriceWithFees
        const isNewGroupTicket = ticket?.groupName !== arr[i - 1]?.groupName

        return (
          <React.Fragment key={ticket.id || ticket.name}>
            {showGroupNameBlock && showGroup && isNewGroupTicket ? (
              <div className="event-detail__tier group-title">
                {ticket.groupName || ''}
              </div>
            ) : null}
            <div
              className={`event-detail__tier ${isSoldOut ? 'disabled' : ''}`}
              id={ticket.id || ticket.name}
            >
              <div className="event-detail__tier-name">
                {ticket.displayName || ticket.name}
                {ticket.descriptionRich && (
                  <>
                    <span
                      aria-hidden
                      className="info-icon"
                      onClick={
                        descriptionTrigger === 'click'
                          ? () => handleDescriptionToggle(ticket.id)
                          : undefined
                      }
                      onMouseEnter={
                        descriptionTrigger === 'hover'
                          ? () => setVisibleDescription(ticket.id)
                          : undefined
                      }
                      onMouseLeave={
                        descriptionTrigger === 'hover'
                          ? () => setVisibleDescription(null)
                          : undefined
                      }
                      data-tooltip-id={`tooltip-${ticket.id}`}
                      data-tooltip-content="View ticket info"
                      style={{
                        marginLeft: 8,
                        cursor: 'pointer',
                        display: 'flex',
                      }}
                    >
                      <InfoIcon />
                    </span>

                    <Tooltip id={`tooltip-${ticket.id}`} place="top">
                      {ticket.description || 'No description available'}
                    </Tooltip>
                  </>
                )}
              </div>
              <div className="event-tickets-container">
                <div className="event-detail__tier-price">
                  {ticketIsDiscounted && <p className="old-price">{discountTicketPriceElem}</p>}
                  <p className={isSoldOut ? 'sold-out' : ''}>{ticketPriceElem}</p>
                  {!isSoldOut && !ticketIsFree && (
                    <p className="fees">
                      {CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL &&
                        (ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)')}
                      {CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH &&
                        `(${ticketPriceWithFees} with fees)`}
                      {CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN &&
                        ticketBreakdown}
                    </p>
                  )}
                </div>
                <div className="event-detail__tier-state" style={{ minWidth: 55 }}>
                  <TicketRow
                    ticketTier={ticket}
                    prevTicketTier={arr[i - 1]}
                    selectedTickets={selectedTickets}
                    handleTicketSelect={ticketSelect}
                    event={event}
                  />
                </div>
              </div>
              {visibleDescription === ticket.id && (
                <div className="ticket-description">
                  <div
                    dangerouslySetInnerHTML={{
                      __html: decodeHTML(ticket.descriptionRich),
                    }}
                  />
                </div>
              )}
            </div>
          </React.Fragment>
        )
      })}
      {!hideTableTicketsHeader && tableTicketsHeaderComponent}
      {tableTickets.map((ticket: any, i: any, arr: any) => {
        const ticketPriceWithoutFees = `${priceSymbol} ${(+ticket.cost).toFixed(2)}`
        const ticketPriceWithFees = `${priceSymbol} ${(+ticket.basePrice).toFixed(2)}`
        const ticketOldPriceWithFees = `${priceSymbol} ${(+ticket.oldBasePrice).toFixed(2)}`
        const ticketOldPriceWithoutFees = `${priceSymbol} ${(+ticket.oldCost).toFixed(2)}`
        const ticketFinalPrice = ticket.feeIncluded && !ticket.isForward
          ? +(ticket.x_face_value || ticket.basePrice)
          : ticket.feeIncluded ? +ticket.basePrice : +ticket.cost
        const ticketFinalPriceFormatted = `${priceSymbol} ${parseFloat(ticketFinalPrice.toFixed(2))}`
        const ticketOldFinalPrice = ticket.feeIncluded && !ticket.isForward
          ? +(ticket.x_face_value || ticket.basePrice)
          : ticket.feeIncluded ? +ticket.oldBasePrice : +ticket.oldCost
        const ticketOldFinalPriceFormatted = `${priceSymbol} ${parseFloat(ticketOldFinalPrice.toFixed(2))}`
        const ticketFeeAmount = (+ticket.basePrice - +ticket.cost).toFixed(2)
        const ticketBreakdown = !ticket.feeIncluded
          ? '(+ fees at checkout)'
          : !ticket.isForward
            ? null
            : (parseFloat(ticketFeeAmount) > 0 ? `(${priceSymbol} ${(+ticket.cost).toFixed(2)} + ${priceSymbol} ${ticketFeeAmount} fee)` : null)

        const isSoldOut =
          ticket.sold_out ||
          !(ticket.displayTicket || ticket.slotGroupId) ||
          ticket.soldOut
        const ticketSelect = (event: any) => {
          const { value } = event.target
          handleTicketSelect(ticket.id, value, true)
        }

        let ticketIsDiscounted = false
        if (ticket.oldPrice && !isSoldOut && ticket.oldPrice !== ticket.price) {
          ticketIsDiscounted = true
        }

        const ticketIsFree = +ticket.price === 0
        const discountTicketPriceElem = CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN
          ? ticketOldFinalPriceFormatted
          : CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded
            ? ticketOldPriceWithoutFees
            : ticketOldPriceWithFees
        const ticketPriceElem = isSoldOut
          ? 'SOLD OUT'
          : ticketIsFree
            ? 'FREE'
            : CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN
              ? ticketFinalPriceFormatted
              : (CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH || !ticket.feeIncluded)
                ? ticketPriceWithoutFees
                : ticketPriceWithFees
        const isNewGroupTicket = ticket?.groupName !== arr[i - 1]?.groupName

        return (
          <React.Fragment key={ticket.id || ticket.name}>
            {showGroupNameBlock && showGroup && isNewGroupTicket ? (
              <div className="event-detail__tier group-title">
                {ticket.groupName || ''}
              </div>
            ) : null}
            <div
              className={`event-detail__tier ${isSoldOut ? 'disabled' : ''}`}
              id={ticket.id || ticket.name}
            >
              <div className="event-detail__tier-name">
                {ticket.displayName || ticket.name}
                {ticket.descriptionRich && (
                  <>
                    <span
                      aria-hidden
                      className="info-icon"
                      onClick={
                        descriptionTrigger === 'click'
                          ? () => handleDescriptionToggle(ticket.id)
                          : undefined
                      }
                      onMouseEnter={
                        descriptionTrigger === 'hover'
                          ? () => setVisibleDescription(ticket.id)
                          : undefined
                      }
                      onMouseLeave={
                        descriptionTrigger === 'hover'
                          ? () => setVisibleDescription(null)
                          : undefined
                      }
                      style={{ marginLeft: 8, cursor: 'pointer', display: 'flex' }}
                      data-tooltip-id={`tooltip-${ticket.id}`}
                      data-tooltip-content="View ticket info"
                    >
                      <InfoIcon />
                    </span>
                    <Tooltip id={`tooltip-${ticket.id}`} place="top">
                      {ticket.description || 'No description available'}
                    </Tooltip>
                  </>
                )}
              </div>
              <div className="event-tickets-container">
                <div className="event-detail__tier-price">
                  {ticketIsDiscounted && <p className="old-price">{discountTicketPriceElem}</p>}
                  <p className={isSoldOut ? 'sold-out' : ''}>{ticketPriceElem}</p>
                  {!isSoldOut && !ticketIsFree && (
                    <p className="fees">
                      {CONFIGS.FEES_STYLE === FEES_STYLES.TRADITIONAL &&
                        (ticket.feeIncluded ? '(incl. Fees)' : '(excl. Fees)')}
                      {CONFIGS.FEES_STYLE === FEES_STYLES.DISPLAY_BOTH &&
                        `(${ticketPriceWithFees} with fees)`}
                      {CONFIGS.FEES_STYLE === FEES_STYLES.FINAL_WITH_BREAKDOWN &&
                        ticketBreakdown}
                    </p>
                  )}
                  {ticket.depositPercent && (
                    <p className="deposits">{ticket.depositPercent + '% DEPOSIT'}</p>
                  )}
                </div>
                <div className="event-detail__tier-state" style={{ minWidth: 55 }}>
                  <TicketRow
                    tableType={true}
                    ticketTier={ticket}
                    prevTicketTier={arr[i - 1]}
                    selectedTickets={selectedTickets}
                    handleTicketSelect={ticketSelect}
                    isSeatMapAllowed={isSeatMapAllowed}
                    event={event}
                  />
                </div>
              </div>
              {visibleDescription === ticket.id && (
                <div className="ticket-description">
                  <div
                    dangerouslySetInnerHTML={{
                      __html: decodeHTML(ticket.descriptionRich),
                    }}
                  />
                </div>
              )}
            </div>
          </React.Fragment>
        )
      })}
    </>
  )
}
