import React, { useState } from 'react'
import Button from '@mui/material/Button/index.js'
import Select from '@mui/material/Select/index.js'
import MenuItem from '@mui/material/MenuItem/index.js'
import Card from '@mui/material/Card/index.js'
import CardContent from '@mui/material/CardContent/index.js'
import CardHeader from '@mui/material/CardHeader/index.js'
import CardActions from '@mui/material/CardActions/index.js'
import Typography from '@mui/material/Typography/index.js'
import { func, instanceOf, node, number, string } from 'prop-types'

import FarmhandContext from '../Farmhand/Farmhand.context.js'

interface TierPurchaseProps {
  description?: string
  onBuyClick: (tier: number) => void
  maxedOutPlaceholder?: React.ReactNode
  money: number
  purchasedTier: number
  renderTierLabel: (tier: any) => React.ReactNode
  tiers: Map<number, { price: number; [key: string]: any }>
  title: string
}

export function TierPurchase({
  description,
  onBuyClick,
  maxedOutPlaceholder,
  money,
  purchasedTier,
  renderTierLabel,
  tiers,
  title,
}: TierPurchaseProps) {
  const [selectedTier, setSelectedTier] = useState<number | string>(
    purchasedTier
  )

  const tierValues = [...tiers.entries()]

  const selectedTierNumber = Number(selectedTier)

  const hasPurchasedTier = (tierLevel: number) => tierLevel <= purchasedTier
  const hasPurchasedHighestTier = hasPurchasedTier(tierValues.slice(-1)[0][0])

  if (hasPurchasedTier(Number(selectedTier))) {
    const nextTierNumber = selectedTierNumber + 1
    const nextTierToPurchase = tiers.get(nextTierNumber)

    if (nextTierToPurchase && money >= nextTierToPurchase.price) {
      setSelectedTier(`${nextTierNumber}`)
    }
  }

  const canPlayerBuySelectedTier = () => {
    const tierToBuy = tiers.get(selectedTierNumber)

    return (
      !!tierToBuy &&
      !hasPurchasedTier(selectedTierNumber) &&
      money >= tierToBuy.price
    )
  }

  const handleBuyClick = () => {
    const canAfford =
      (tiers.get(selectedTierNumber)?.price ?? Infinity) <= money

    if (canAfford) {
      onBuyClick(selectedTierNumber)
    }
  }

  const handleTierSelected = ({ target: { value } }: any) => {
    setSelectedTier(value)
  }

  return (
    <Card className="TierPurchase">
      <CardHeader {...{ title }} />
      {description && (
        <CardContent>
          <Typography>{description}</Typography>
        </CardContent>
      )}
      {hasPurchasedHighestTier && maxedOutPlaceholder ? (
        <CardContent>
          <Typography>
            <strong>{maxedOutPlaceholder}</strong>
          </Typography>
        </CardContent>
      ) : (
        <CardActions>
          <Button
            {...{
              color: 'primary',
              disabled: !canPlayerBuySelectedTier(),
              onClick: handleBuyClick,
              variant: 'contained',
            }}
          >
            Buy
          </Button>
          <Select
            variant="standard"
            sx={{
              flexGrow: 1,
              m: 0,
              ml: '1rem',
              maxWidth: 300,
            }}
            {...{
              onChange: handleTierSelected,
              value: Number(selectedTier) > 0 ? selectedTier : '',
            }}
          >
            {tierValues.map(([id, tier]) => (
              <MenuItem
                key={id}
                value={id}
                disabled={money < tier.price || hasPurchasedTier(id)}
              >
                {renderTierLabel(tier)}
              </MenuItem>
            ))}
          </Select>
        </CardActions>
      )}
    </Card>
  )
}

TierPurchase.propTypes = {
  description: string,
  onBuyClick: func.isRequired,
  maxedOutPlaceholder: node,
  money: number.isRequired,
  purchasedTier: number.isRequired,
  renderTierLabel: func.isRequired,
  tiers: instanceOf(Map),
  title: string.isRequired,
}

export default function Consumer(
  props: Partial<Parameters<typeof TierPurchase>[0]>
) {
  return (
    <FarmhandContext.Consumer>
      {({ gameState, handlers }) => (
        <TierPurchase
          {...({
            ...gameState,
            ...handlers,
            ...props,
          } as Parameters<typeof TierPurchase>[0])}
        />
      )}
    </FarmhandContext.Consumer>
  )
}
