import React, { useEffect, useMemo, useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { ColorValue } from "react-native";
// import { COLORS } from "@/app";

interface ChipDistributionSummaryProps {
  playerCount: number;
  buyInAmount: number;
  totalChipsCount: number[];
  colors?: ColorValue[];
}

const ChipDistributionSummary = ({
  playerCount,
  buyInAmount,
  totalChipsCount,
  colors = ["white", "red", "green", "blue", "black"],
}: ChipDistributionSummaryProps) => {
  const validDenominations: validDenomination[] = [
    0.05, 0.1, 0.25, 0.5, 1, 2, 2.5, 5, 10, 20, 50, 100,
  ];
  const [denominations, setDenominations] = useState<validDenomination[]>([]);
  const [distributions, setDistributions] = useState<number[]>([]);

  type validDenomination =
    | 0.05
    | 0.1
    | 0.25
    | 0.5
    | 1
    | 2
    | 2.5
    | 5
    | 10
    | 20
    | 50
    | 100;

  // Re-organize the inputs in a map for convience
  const chipMap: Map<ColorValue, number> = useMemo(() => {
    const m: Map<ColorValue, number> = new Map<ColorValue, number>();
    totalChipsCount.map((v, i) => {
      m.set(colors[i], v);
    });
    return m;
  }, [playerCount, buyInAmount, totalChipsCount]);

  // Helper function to return the closest (but lower) valid denomination to the target
  const findFloorDenomination = (target: number): validDenomination => {
    let current: validDenomination = validDenominations[0];
    validDenominations.forEach((value, index) => {
      if (value < target) current = value;
    });
    return current;
  };

  // Bound for the value of the highest chip
  const maxDenomination = useMemo(() => {
    if (chipMap.size > 3) {
      return findFloorDenomination(buyInAmount / 3);
    } else {
      return findFloorDenomination(buyInAmount / 4);
    }
  }, [chipMap]);

  // Total value of the pot
  const potValue = useMemo(
    () => buyInAmount * playerCount,
    [buyInAmount, playerCount]
  );

  const totalValue = useMemo(() => {
    let value = 0;
    for (let i = 0; i < totalChipsCount.length; i++) {
      value += distributions[i] * denominations[i];
    }
    return value;
  }, [distributions, denominations]);

  // Maximum quantity of each chip which may be distributed to a single player before running out
  const maxPossibleDistribution = useMemo(
    () => totalChipsCount.map((v) => Math.floor(v / playerCount)),
    [totalChipsCount, playerCount]
  );

  const redenominate = (
    invalidDenomination: validDenomination[],
    shuffleIndex: number
  ): validDenomination[] => {
    console.log("Old Denominations ", invalidDenomination);
    const newDenomination: validDenomination[] = [];
    for (let i = invalidDenomination.length - 1; i >= 0; i--) {
      if (i > shuffleIndex) {
        newDenomination.push(invalidDenomination[i]);
      } else if (i == shuffleIndex) {
        newDenomination.push(invalidDenomination[i]);
      } else {
        const nextLowestDenominationIndex = Math.max(
          validDenominations.indexOf(invalidDenomination[i]) - 1,
          0
        );
        newDenomination.push(validDenominations[nextLowestDenominationIndex]);
      }
    }
    newDenomination.reverse();
    console.log("New Denominations ", newDenomination);
    return newDenomination;
  };

  const redenominate2 = (
    invalidDenomination: validDenomination[],
    shuffleIndex: number
  ): validDenomination[] => {
    console.log("Old Denominations ", invalidDenomination);
    let moved = false;
    const newDenomination: validDenomination[] = [];
    for (let i = invalidDenomination.length - 1; i >= 0; i--) {
      if (i > shuffleIndex) {
        newDenomination.push(invalidDenomination[i]);
      } else if (i == shuffleIndex) {
        newDenomination.push(invalidDenomination[i]);
      } else if (i < shuffleIndex && !moved) {
        const nextLowestDenominationIndex = Math.max(
          validDenominations.indexOf(invalidDenomination[i]) - 1,
          0
        );
        newDenomination.push(validDenominations[nextLowestDenominationIndex]);
        moved = true;
      } else {
        newDenomination.push(invalidDenomination[i]);
      }
    }
    newDenomination.reverse();
    console.log("New Denominations ", newDenomination);
    return newDenomination;
  };

  useEffect(() => {
    // const testDistribution: Map<ColorValue, number> = new Map();
    let testDenomination: validDenomination[] = [];

    const numColors = chipMap.size;
    const testDistribution: number[] = [];
    for (let i = 0; i < numColors; ++i) {
      testDistribution.push(0);
    }

    let numColorsRemaining = numColors;
    // testDistribution.set(colors[numColors - 1], maxDenomination);
    testDenomination.push(maxDenomination);
    numColorsRemaining -= 1;
    let currentDenominationIndex: number =
      validDenominations.indexOf(maxDenomination);
    while (numColorsRemaining > 0) {
      numColorsRemaining -= 1;
      currentDenominationIndex -= 1;
      const currentDemoniation = validDenominations[currentDenominationIndex];
      testDenomination.push(currentDemoniation);
    }
    testDenomination.reverse();

    // console.log("BUY IN: ", buyInAmount);
    // console.log("PLAYER COUNT ", playerCount);

    // DISTRIBUTE
    let remainingValue = buyInAmount;
    // console.log("\ntest Denomination", testDenomination);
    // console.log("test distribution ", testDistribution);
    // console.log("remainingChips", remainingChips);
    // console.log("remaining value ", remainingValue);

    //First distribute one of each chip to each player
    // for (let i = numColors - 1; i >= 0; i--) {
    //   testDistribution[i] = testDistribution[i] + 1;
    //   remainingChips[i] = remainingChips[i] - 1;
    //   remainingValue = remainingValue - testDenomination[i];
    // }
    // console.log("\ntest Denomination", testDenomination);
    // console.log("test distribution ", testDistribution);
    // console.log("remainingChips", remainingChips);
    // console.log("remaining value ", remainingValue);

    //Then, greedy approach to distribute remaining chips

    let fail = true;
    let failCount = 0;
    while (fail && failCount < 10) {
      let stop = false;
      while (remainingValue > 0 && !stop) {
        let distributed = false;
        for (let i = numColors - 1; i >= 0; i = i - 1) {
          console.log("i: ", i);
          if (testDistribution[i] < maxPossibleDistribution[i]) {
            if (remainingValue >= testDenomination[i]) {
              // console.log("distributing ", testDenomination[i]);
              testDistribution[i] = testDistribution[i] + 1;
              remainingValue = remainingValue - testDenomination[i];
              distributed = true;
            } else {
              // console.log(
              //   "Max distribution reached for value",
              //   testDenomination[i],
              //   "remaining value is ",
              //   remainingValue
              // );
            }
          } else {
            // console.log("no more chips left for ", colors[i]);
          }
        }
        if (distributed == false) {
          stop = true;
        }
      }
      if (remainingValue !== 0) {
        console.log(`\n Failed: ${remainingValue} !== 0 Redenominating  `);
        const redenominateIndex = failCount % numColors;
        console.log("Redenominating index  ", redenominateIndex);
        testDenomination = redenominate2(testDenomination, redenominateIndex);
        failCount += 1;
        fail = true;
      } else {
        fail = false;
      }
    }

    // console.log("\ntest Denomination", testDenomination);
    // console.log("test distribution ", testDistribution);
    // console.log("remainingChips", remainingChips);
    // console.log("remaining value ", remainingValue);

    setDenominations(testDenomination);
    setDistributions(testDistribution);
  }, [chipMap, maxDenomination, buyInAmount, playerCount]);

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Chip Distribution Summary:</Text>
      {colors.map((color, index) => (
        <View style={styles.chipContainer} key={index}>
          <Text style={{ ...styles.chipText, color: color }}>
            {String(color).charAt(0).toUpperCase() + String(color).slice(1)}{" "}
            chips: {distributions[index]} ( ${denominations[index]} each)
          </Text>
        </View>
      ))}
      <Text style={styles.chipText}>
        Total Value:{totalValue} Pot Value: {potValue}
      </Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    marginTop: 20,
    padding: 15,
    backgroundColor: "#F8F9FA",
    borderRadius: 10,
  },
  title: {
    fontSize: 18,
    fontWeight: "bold",
    marginBottom: 10,
  },
  chipContainer: {
    marginTop: 10,
    backgroundColor: "#888",
  },
  chipText: {
    fontSize: 20,
    marginVertical: 2,
    fontWeight: "bold",
  },
  noDataText: {
    fontSize: 16,
    color: "gray",
  },
});

export default ChipDistributionSummary;
