/**
 * React component for displaying a single augmentation for purchase through
 * the faction UI
 */
import React, { useState } from "react";

import { hasAugmentationPrereqs, purchaseAugmentation } from "../../Faction/FactionHelpers";
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";

import { Augmentations } from "../Augmentations";
import { AugmentationNames } from "../data/AugmentationNames";
import { Faction } from "../../Faction/Faction";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Settings } from "../../Settings/Settings";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation";

import { CheckBox, CheckBoxOutlineBlank, Verified, Info, Report, CheckCircle } from "@mui/icons-material";
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material";
import { TableCell } from "../../ui/React/Table";
import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers";
import { Augmentation } from "../Augmentation";

// interface IReqProps {
//   augName: string;
//   p: IPlayer;
//   hasReq: boolean;
//   rep: number;
//   hasRep: boolean;
//   cost: number;
//   hasCost: boolean;
// }

// function Requirements(props: IReqProps): React.ReactElement {
//   const aug = Augmentations[props.augName];
//   if (!props.hasReq) {
//     return (
//       <TableCell key={1} colSpan={2}>
//         <Typography color="error">
//           Requires{" "}
//           {aug.prereqs.map((aug, i) => (
//             <AugFormat key={i} name={aug} />
//           ))}
//         </Typography>
//       </TableCell>
//     );
//   }

//   return (
//     <React.Fragment key="f">
//       <TableCell key={1}>
//         <Typography>
//           <Money money={props.cost} player={props.p} />
//         </Typography>
//       </TableCell>
//       <TableCell key={2}>
//         <Typography color={props.hasRep ? "primary" : "error"}>
//           Requires <Reputation reputation={props.rep} /> faction reputation
//         </Typography>
//       </TableCell>
//     </React.Fragment>
//   );
// }

interface IPreReqsProps {
  player: IPlayer;
  aug: Augmentation;
}

const PreReqs = (props: IPreReqsProps): React.ReactElement => {
  const ownedPreReqs = props.aug.prereqs.filter((aug) => props.player.hasAugmentation(aug));
  const hasPreReqs = props.aug.prereqs.length > 0 && ownedPreReqs.length === props.aug.prereqs.length;

  return (
    <Tooltip
      title={
        <Typography sx={{ color: Settings.theme.money }}>
          This Augmentation has the following pre-requisite(s):
          {props.aug.prereqs.map((preAug) => (
            <Requirement
              fulfilled={props.player.hasAugmentation(preAug)}
              value={preAug}
              color={Settings.theme.money}
              key={preAug}
            />
          ))}
        </Typography>
      }
    >
      <Typography
        variant="body2"
        sx={{
          display: "flex",
          alignItems: "center",
          color: hasPreReqs ? Settings.theme.successlight : Settings.theme.error,
        }}
      >
        {hasPreReqs ? (
          <>
            <CheckCircle fontSize="small" sx={{ mr: 1 }} />
            Pre-requisites Owned
          </>
        ) : (
          <>
            <Report fontSize="small" sx={{ mr: 1 }} />
            Missing {props.aug.prereqs.length - ownedPreReqs.length} pre-requisite(s)
          </>
        )}
      </Typography>
    </Tooltip>
  );
};

interface IExclusiveProps {
  player: IPlayer;
  aug: Augmentation;
}

const Exclusive = (props: IExclusiveProps): React.ReactElement => {
  return (
    <Tooltip
      title={
        <Typography sx={{ color: Settings.theme.money }}>
          This Augmentation can only be acquired from the following source(s):
          <ul>
            <li>
              <b>{props.aug.factions[0]}</b> faction
            </li>
            {props.player.canAccessGang() && (
              <li>
                Certain <b>gangs</b>
              </li>
            )}
            {props.player.canAccessGrafting() && (
              <li>
                <b>Grafting</b>
              </li>
            )}
          </ul>
        </Typography>
      }
    >
      <Verified sx={{ ml: 1, color: Settings.theme.money }} />
    </Tooltip>
  );
};

interface IReqProps {
  value: string;
  color: string;
  fulfilled: boolean;
}

const Requirement = (props: IReqProps): React.ReactElement => {
  return (
    <Typography sx={{ display: "flex", alignItems: "center", color: props.color }}>
      {props.fulfilled ? <CheckBox sx={{ mr: 1 }} /> : <CheckBoxOutlineBlank sx={{ mr: 1 }} />}
      {props.value}
    </Typography>
  );
};

interface IPurchaseableAugsProps {
  augNames: string[];
  player: IPlayer;

  canPurchase: (player: IPlayer, aug: Augmentation) => boolean;
  purchaseAugmentation: (player: IPlayer, aug: Augmentation, showModal: (open: boolean) => void) => void;

  rep?: number;
}

export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => {
  return (
    <Container
      maxWidth="md"
      disableGutters
      sx={{ mx: 0, display: "grid", gridTemplateColumns: "repeat(1, 1fr)", gap: 1 }}
    >
      {props.augNames.map((augName: string) => {
        const aug = Augmentations[augName];

        const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
        const description = (
          <>
            {info}
            <br />
            <br />
            {aug.stats}
          </>
        );

        return (
          <Paper key={augName} sx={{ p: 1, display: "grid", gridTemplateColumns: "minmax(0, 3fr) 1fr", gap: 1 }}>
            <Box sx={{ display: "flex", alignItems: "center" }}>
              <Button
                onClick={() =>
                  props.purchaseAugmentation(props.player, aug, (_open: boolean): void => {
                    null;
                  })
                }
                disabled={!props.canPurchase(props.player, aug)}
                sx={{ width: "48px", height: "48px", float: "left", clear: "none", mr: 1 }}
              >
                Buy
              </Button>

              <Box sx={{ maxWidth: "85%" }}>
                <Box sx={{ display: "flex", alignItems: "center" }}>
                  <Tooltip
                    title={
                      <>
                        <Typography variant="h5">
                          {augName}
                          {augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
                        </Typography>
                        <Typography>{description}</Typography>
                      </>
                    }
                  >
                    <Info sx={{ mr: 1 }} color="info" />
                  </Tooltip>
                  <Typography
                    variant="h6"
                    sx={{
                      textOverflow: "ellipsis",
                      whiteSpace: "nowrap",
                      overflow: "hidden",
                    }}
                  >
                    {aug.name}
                    {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
                  </Typography>
                  {aug.factions.length === 1 && <Exclusive player={props.player} aug={aug} />}
                </Box>

                {aug.prereqs.length > 0 && <PreReqs player={props.player} aug={aug} />}
              </Box>
            </Box>

            <Box sx={{ display: "flex", alignItems: "center" }}>
              <span>
                <Requirement
                  fulfilled={aug.baseCost === 0 || props.player.money > aug.baseCost}
                  value={numeralWrapper.formatMoney(aug.baseCost)}
                  color={Settings.theme.money}
                />
                {props.rep !== undefined && (
                  <Requirement
                    fulfilled={props.rep >= aug.baseRepRequirement}
                    value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`}
                    color={Settings.theme.rep}
                  />
                )}
              </span>
            </Box>
          </Paper>
        );
      })}
    </Container>
  );
};

interface IPurchaseableAugProps {
  augName: string;
  faction: Faction;
  p: IPlayer;
  rerender: () => void;
  owned?: boolean;
}

export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.ReactElement {
  const [open, setOpen] = useState(false);
  const aug = Augmentations[props.augName];
  if (aug == null) throw new Error(`aug ${props.augName} does not exists`);

  if (aug == null) {
    console.error(
      `Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,
    );
    return <></>;
  }

  const moneyCost = aug.baseCost;
  const repCost = aug.baseRepRequirement;
  const hasReq = hasAugmentationPrereqs(aug);
  const hasRep = props.faction.playerReputation >= repCost;
  const hasCost = aug.baseCost === 0 || props.p.money > aug.baseCost;

  // Determine UI properties
  const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";

  // Determine button txt
  let btnTxt = aug.name;
  if (aug.name === AugmentationNames.NeuroFluxGovernor) {
    btnTxt += ` - Level ${getNextNeuroFluxLevel()}`;
  }

  let tooltip = <></>;
  if (typeof aug.info === "string") {
    tooltip = (
      <>
        <span>{aug.info}</span>
        <br />
        <br />
        {aug.stats}
      </>
    );
  } else
    tooltip = (
      <>
        {aug.info}
        <br />
        <br />
        {aug.stats}
      </>
    );

  function handleClick(): void {
    if (color === "error") return;
    if (!Settings.SuppressBuyAugmentationConfirmation) {
      setOpen(true);
    } else {
      purchaseAugmentation(aug, props.faction);
      props.rerender();
    }
  }

  return (
    <TableRow>
      {!props.owned && (
        <TableCell key={0}>
          <Button onClick={handleClick} color={color}>
            Buy
          </Button>
          <PurchaseAugmentationModal
            open={open}
            onClose={() => setOpen(false)}
            aug={aug}
            faction={props.faction}
            rerender={props.rerender}
          />
        </TableCell>
      )}
      <TableCell key={1}>
        <Box display="flex">
          <Tooltip title={<Typography>{tooltip}</Typography>} placement="top">
            <Typography>{btnTxt}</Typography>
          </Tooltip>
        </Box>
      </TableCell>
      {!props.owned && (
        <Requirements
          key={2}
          augName={props.augName}
          p={props.p}
          cost={moneyCost}
          rep={repCost}
          hasReq={hasReq}
          hasRep={hasRep}
          hasCost={hasCost}
        />
      )}
    </TableRow>
  );
}
