import "./QuestProgress.css";

import classnames from "classnames";
import React, { useState } from "react";
import { GameState, Quest, ResourceType } from "../data/GameState";
import { UpdaterGeneratorType2 } from "../lib/util/updaterGenerator";
import { Grade, remapEfficiencyGradeToNumber } from "../game/EfficiencyCalculator";

type Props = {
  spSpentThisQuest: number | undefined;
  createQuestCb: () => void;
  activeQuest: Quest | undefined;
  playerResourceAmounts?: { [k in ResourceType]: number };
  updaters: UpdaterGeneratorType2<GameState, GameState>["playerSave"];
  efficiencyGrade: Grade;
  score: GameState["playerSave"]["score"];
  questInitialAmount: number;
};
type QuestScoreReward = {
  total: number;
  scoreComponents: ScoreComponent[];
};
type ScoreComponent = {
  // inputAmount: number | string;
  // inputTitle: string;
  // outputScore: number;
  // outputDescription: string;
  scoreAmount: number;
  scoreReason: string;
};


export default React.memo(QuestProgressComponent);

function calculateQuestScoreReward(grade: Grade): QuestScoreReward {
  const scoreComponents = [
    {
      scoreReason: 'Quest completed',
      scoreAmount: 50,
    },
    {
      scoreReason: `Efficiency: "${grade}"`,
      scoreAmount: remapEfficiencyGradeToNumber(grade) * 25,
    }
  ];
  const total = scoreComponents.reduce((pv, cv) => pv + cv.scoreAmount, 0);
  return {
    total,
    scoreComponents,
  };
}

function QuestProgressComponent({
  activeQuest,
  spSpentThisQuest,
  createQuestCb,
  playerResourceAmounts,
  updaters,
  efficiencyGrade,
  // score,
  questInitialAmount,
}: Props) {
  /**
   * activeQuest === undefined => no active quest, need to start quest
   * isQuestComplete => can finish the quest to generate rewards
   * rewards ready => can accept rewards to increment score; cannot generate a new quest
   */
  const isQuestComplete =
    activeQuest &&
    (playerResourceAmounts?.[activeQuest.resourceType] || 0) >= activeQuest.resourceAmount;

  const [didAcceptRewards, setDidAcceptRewards] = useState(true);
  const [scoreReward, setScoreReward] = useState<QuestScoreReward | undefined>();

  const handleStartQuest = () => {
    createQuestCb();
  };

  const doFinishQuest = () => {
    updaters.activeQuest.enqueueUpdate(() => {
      return undefined;
    });
    setScoreReward(calculateQuestScoreReward(efficiencyGrade));
    setDidAcceptRewards(false);
  };

  const doClaimRewards = () => {
    if (scoreReward) {
      updaters.score.enqueueUpdate((prev) => {
        return prev + scoreReward.total;
      });
      setDidAcceptRewards(true);
    }
  };

  return (
    <>
      {<Score doClaimRewards={doClaimRewards} scoreReward={scoreReward} didAcceptRewards={didAcceptRewards}/>}
      {activeQuest === undefined ? (
        <>
          <h2>No active quest
          </h2>
          <br></br>
          <button className="button" onClick={handleStartQuest} disabled={!didAcceptRewards}>
            {didAcceptRewards ? 'Start a quest' : 'Claim rewards first!'}
          </button>
          <br></br>
          <br></br>
          <br></br>
        </>
      ) : (
        <>
            <h2> Active quest: </h2>
            <table className={classnames({ table: true })}>
              <tr>
                <td>
                  Initial
                </td>
                <td>
                  {questInitialAmount} {activeQuest.resourceType}
                </td>
              </tr>
              <tr>
                <td>
                  Current
                </td>
                <td>
                  {playerResourceAmounts?.[activeQuest.resourceType]} {activeQuest.resourceType}
                </td>
              </tr>
              <tr>
                <td>
                  Target
                </td>
                <td>
                  {activeQuest.resourceAmount} {activeQuest.resourceType}
                </td>
              </tr>
              <tr>
                <td>
                  SP spent
                </td>
                <td>
                  {spSpentThisQuest === undefined ? "" : spSpentThisQuest}
                </td>
              </tr>
              <tr>
                <td>
                  Efficiency
                </td>
                <td>
                  {efficiencyGrade}
                </td>
              </tr>
            </table>

            {isQuestComplete ? (
              <>
                <br></br>
                <button className="button" onClick={doFinishQuest}>
                  Finish quest
                  </button>
              </>
            ) : (
                <></>
              )}
        </>
      )}
    </>
  );
}

function Score({
  scoreReward,
  doClaimRewards,
  didAcceptRewards,
}: {
    scoreReward: QuestScoreReward | undefined;
    doClaimRewards: () => void;
    didAcceptRewards: boolean;
}) {
  if (scoreReward === undefined) {
    return (<> </>);
  }

  return (
    <>
      <h3>Quest Rewards</h3>
      <div>+{scoreReward.total} to your score! </div>
      <br></br>
      <table className={classnames({ table: true })}>
        {scoreReward.scoreComponents.map((it) => (
          <tr>
            <td> +{it.scoreAmount} score </td>
            <td> {it.scoreReason} </td>
          </tr>))
        }
      </table>
      <br></br>
      {(
        didAcceptRewards ? (<> </>) : 
          (
      <button
        className="button"
        onClick={() => doClaimRewards()}>
        Claim rewards!
      </button>
          )
      )}
    </>
  );
}

// function formatDelta(d: number): string {
//   return d < 0 ? d.toString() : "+" + d.toString();
// }