import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Card,
  CardHeader,
  CardTitle,
  CardContent,
  CardFooter,
  CardDescription,
} from "@/components/ui/card";
import { Plus, Minus, Trash2, ArrowLeft, Pencil } from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";

interface ParticipantSetup {
  id: number;
  name: string;
}

interface Prize {
  id: string;
  name: string;
  points: number;
  quantity: number;
}

interface Participant {
  id: number;
  name: string;
  pointsAvailable: number;
  prizes: Prize[];
}

interface EditingPrize {
  participantId: number;
  prizeId: string;
  name: string;
  points: string;
  quantity: string;
}

interface StoredData {
  stage: Stage;
  numParticipants: number;
  participantSetup: ParticipantSetup[];
  pointInputs: number[];
  participants: Participant[];
  totalPoints: number;
}

type Stage = "setup" | "points" | "tracking";

const STORAGE_KEY = "arcadeTrackerData";

const ArcadeTracker: React.FC = () => {
  const [stage, setStage] = useState<Stage>("setup");
  const [numParticipants, setNumParticipants] = useState<number>(3);
  const [pointInputs, setPointInputs] = useState<number[]>([]);
  const [participants, setParticipants] = useState<Participant[]>([]);
  const [totalPoints, setTotalPoints] = useState<number>(0);
  const [newPrizeName, setNewPrizeName] = useState<string>("");
  const [newPrizePoints, setNewPrizePoints] = useState<string>("");
  const [newPrizeQuantity, setNewPrizeQuantity] = useState<string>("1");
  const [participantSetup, setParticipantSetup] = useState<ParticipantSetup[]>(
    []
  );
  const [showResetDialog, setShowResetDialog] = useState(false);
  const [editingParticipantId, setEditingParticipantId] = useState<
    number | null
  >(null);
  const [editingPrize, setEditingPrize] = useState<EditingPrize | null>(null);

  useEffect(() => {
    // Initialize participant setup when component mounts
    if (participantSetup.length === 0) {
      setParticipantSetup(Array(numParticipants)
        .fill(null)
        .map((_, i) => ({
          id: i + 1,
          name: `Player ${i + 1}`,
        }))
      );
    }
  }, [participantSetup.length, numParticipants]);

  useEffect(() => {
    const savedData = localStorage.getItem(STORAGE_KEY);
    if (savedData) {
      try {
        const parsed = JSON.parse(savedData) as StoredData;
        setStage(parsed.stage);
        setNumParticipants(parsed.numParticipants);
        setParticipantSetup(parsed.participantSetup || []);
        setPointInputs(parsed.pointInputs);
        setParticipants(parsed.participants);
        setTotalPoints(parsed.totalPoints);
      } catch (error) {
        console.error("Error parsing saved data:", error);
      }
    }
  }, []);

  useEffect(() => {
    const dataToSave: StoredData = {
      stage,
      numParticipants,
      participantSetup,
      pointInputs,
      participants,
      totalPoints,
    };
    localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
  }, [
    stage,
    numParticipants,
    pointInputs,
    participants,
    totalPoints,
    participantSetup,
  ]); // Add participantSetup

  const handleParticipantNameChange = (id: number, name: string) => {
    setParticipantSetup((prev) =>
      prev.map((p) => (p.id === id ? { ...p, name } : p))
    );
  };

  const handleNumParticipantsChange = (change: number) => {
    const newNum = Math.max(2, Math.min(10, numParticipants + change));
    setNumParticipants(newNum);

    // Update participant setup array
    setParticipantSetup((prev) => {
      const newSetup = Array(newNum)
        .fill(null)
        .map((_, i) => ({
          id: i + 1,
          name: prev[i]?.name || `Player ${i + 1}`,
        }));
      return newSetup;
    });
  };

  const handleUpdatePoints = () => {
    const total = pointInputs.reduce((sum, points) => sum + points, 0);
    const pointsPerPerson = Math.floor(total / numParticipants);

    // Update each participant's points while preserving prizes
    const updatedParticipants = participantSetup.map((setup) => {
      const existingParticipant = participants.find((p) => p.id === setup.id);
      const currentPrizePoints =
        existingParticipant?.prizes.reduce(
          (sum, prize) => sum + prize.points,
          0
        ) || 0;

      return {
        id: setup.id,
        name: setup.name,
        pointsAvailable: pointsPerPerson - currentPrizePoints,
        prizes: existingParticipant?.prizes || [],
      };
    });
    setTotalPoints(total);
    setParticipants(updatedParticipants);
    setStage("tracking");
  };

  const handleAddPrize = (participantId: number) => {
    if (editingPrize) {
      // We're editing an existing prize
      const points = parseInt(newPrizePoints) || 0;
      const quantity = parseInt(newPrizeQuantity) || 1;

      setParticipants((current) =>
        current.map((p) => {
          if (p.id === participantId) {
            const oldPrize = p.prizes.find((prize) => prize.id === editingPrize.prizeId);
            const oldPoints = (oldPrize?.points || 0) * (oldPrize?.quantity || 1);
            const newPoints = points * quantity;
            
            return {
              ...p,
              pointsAvailable: p.pointsAvailable + oldPoints - newPoints,
              prizes: p.prizes.map((prize) =>
                prize.id === editingPrize.prizeId
                  ? {
                      ...prize,
                      name: newPrizeName || "Prize",
                      points,
                      quantity,
                    }
                  : prize
              ),
            };
          }
          return p;
        })
      );
    } else {
      // We're adding a new prize
      const points = parseInt(newPrizePoints) || 0;
      const quantity = parseInt(newPrizeQuantity) || 1;

      setParticipants((current) =>
        current.map((p) => {
          if (p.id === participantId) {
            return {
              ...p,
              pointsAvailable: p.pointsAvailable - points * quantity,
              prizes: [
                ...p.prizes,
                {
                  id: Date.now().toString(),
                  name: newPrizeName || "Prize",
                  points,
                  quantity,
                },
              ],
            };
          }
          return p;
        })
      );
    }

    // Clear inputs and close dialog
    setNewPrizeName("");
    setNewPrizePoints("");
    setNewPrizeQuantity("1");
    setEditingParticipantId(null);
    setEditingPrize(null);
  };

  const removePrize = (participantId: number, prizeId: string) => {
    setParticipants(
      participants.map((p) => {
        if (p.id === participantId) {
          const prizeToRemove = p.prizes.find((prize) => prize.id === prizeId);
          return {
            ...p,
            pointsAvailable: p.pointsAvailable + (prizeToRemove?.points || 0) * (prizeToRemove?.quantity || 1),
            prizes: p.prizes.filter((prize) => prize.id !== prizeId),
          };
        }
        return p;
      })
    );
  };

  const handlePointInput = (index: number, value: string) => {
    const newInputs = [...pointInputs];
    newInputs[index] = value === "" ? 0 : parseInt(value) || 0;
    setPointInputs(newInputs);
  };

  const resetApp = () => {
    localStorage.removeItem(STORAGE_KEY);
    setStage("setup");
    setNumParticipants(3);
    setParticipantSetup([
      { id: 1, name: "Player 1" },
      { id: 2, name: "Player 2" },
      { id: 3, name: "Player 3" },
    ]);
    setPointInputs([]);
    setParticipants([]);
    setTotalPoints(0);
    setShowResetDialog(false);
  };

  const renderSetupStage = () => (
    <div className="p-4 max-w-md mx-auto">
      <Card className="shadow-lg">
        <CardHeader>
          <CardTitle className="text-2xl">Arcade Point Tracker</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="space-y-6">
            <div>
              <div>Number of participants:</div>
              <div className="flex items-center gap-4 mt-2">
                <Button
                  variant="outline"
                  size="icon"
                  onClick={() => handleNumParticipantsChange(-1)}
                  disabled={numParticipants <= 2}
                >
                  <Minus className="h-4 w-4" />
                </Button>
                <div className="text-xl font-medium w-8 text-center">
                  {numParticipants}
                </div>
                <Button
                  variant="outline"
                  size="icon"
                  onClick={() => handleNumParticipantsChange(1)}
                  disabled={numParticipants >= 10}
                >
                  <Plus className="h-4 w-4" />
                </Button>
              </div>
            </div>
            <div className="space-y-4">
              <div>Enter participant names:</div>
              {participantSetup.map((p, index) => (
                <div key={p.id} className="flex gap-2">
                  <Input
                    value={p.name}
                    onChange={(e) =>
                      handleParticipantNameChange(p.id, e.target.value)
                    }
                    placeholder={`Player ${index + 1}`}
                    onClick={(e) => (e.target as HTMLInputElement).select()}
                    className="transition-colors focus:bg-accent focus:text-accent-foreground"
                  />
                </div>
              ))}
            </div>
            <Button
              className="w-full"
              onClick={() => {
                setPointInputs(Array(numParticipants).fill(0));
                setStage("points");
              }}
              disabled={participantSetup.some((p) => !p.name.trim())}
            >
              Next
            </Button>
          </div>
        </CardContent>
      </Card>
    </div>
  );

  const renderPointsStage = () => (
    <div className="p-4 max-w-md mx-auto">
      <Card className="shadow-lg">
        <CardHeader>
          <CardTitle className="text-xl">Enter Points</CardTitle>
          <CardDescription>Input the points on each participant&apos;s card</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            {pointInputs.map((points, index) => (
              <div key={index}>
                <label htmlFor={`card-${index}`}>{participantSetup[index].name}&apos;s points:</label>
                <Input
                  id={`card-${index}`}
                  type="text"
                  inputMode="numeric"
                  value={pointInputs[index]}
                  onChange={(e) => handlePointInput(index, e.target.value)}
                  className="mt-1"
                  placeholder="Enter points"
                />
              </div>
            ))}
          </div>
        </CardContent>
        <CardFooter className="flex justify-between">
          <Button variant="outline" onClick={() => setStage("setup")}>
            <ArrowLeft className="w-4 h-4 mr-2" />
            Back
          </Button>
          <Button
            onClick={handleUpdatePoints} // Changed from calculatePoints
            disabled={pointInputs.some((p) => !p)}
          >
            Calculate
          </Button>{" "}
        </CardFooter>
      </Card>
    </div>
  );

  const renderTrackingStage = () => (
    <>
      <div className="fixed top-0 left-0 right-0 z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
        <div className="max-w-md mx-auto p-4">
          <Card className="shadow-lg">
            <CardHeader className="space-y-2">
              <div className="flex justify-between items-start gap-4">
                <CardTitle className="flex flex-col gap-1">
                  <div>Total Points: {totalPoints}</div>
                  <div className="text-base font-normal text-muted-foreground">
                    Points Used:{" "}
                    {participants.reduce(
                      (total, p) =>
                        total +
                        p.prizes.reduce((sum, prize) => sum + prize.points * prize.quantity, 0),
                      0
                    )}
                  </div>
                </CardTitle>
                <div className="space-x-2 flex-shrink-0">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setStage("points")}
                  >
                    <ArrowLeft className="h-4 w-4" />
                    Edit
                  </Button>
                  <Button
                    variant="destructive"
                    size="sm"
                    onClick={() => setShowResetDialog(true)}
                  >
                    <Trash2 className="h-4 w-4" />
                    Reset
                  </Button>
                </div>
              </div>
              <div className="space-y-1">
                <Progress
                  value={
                    (participants.reduce(
                      (total, p) =>
                        total +
                        p.prizes.reduce((sum, prize) => sum + prize.points * prize.quantity, 0),
                      0
                    ) /
                      totalPoints) *
                    100
                  }
                  className={`h-2 ${
                    participants.reduce(
                      (total, p) =>
                        total +
                        p.prizes.reduce((sum, prize) => sum + prize.points * prize.quantity, 0),
                      0
                    ) > totalPoints
                      ? "[&>div]:bg-destructive"
                      : ""
                  }`}
                />
                <CardDescription
                  className={`text-right text-xs ${
                    participants.reduce(
                      (total, p) =>
                        total +
                        p.prizes.reduce((sum, prize) => sum + prize.points * prize.quantity, 0),
                      0
                    ) > totalPoints
                      ? "text-destructive font-medium"
                      : ""
                  }`}
                >
                  {(
                    (participants.reduce(
                      (total, p) =>
                        total +
                        p.prizes.reduce((sum, prize) => sum + prize.points * prize.quantity, 0),
                      0
                    ) /
                      totalPoints) *
                    100
                  ).toFixed(1)}
                  % used
                </CardDescription>
              </div>
            </CardHeader>
          </Card>
        </div>
      </div>

      <div className="max-w-md mx-auto">
        <div className="h-[150px]" /> {/* Spacer for fixed header */}
        <div className="p-4 space-y-4">
          <Dialog open={showResetDialog} onOpenChange={setShowResetDialog}>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Reset Application</DialogTitle>
                <DialogDescription>
                  Are you sure you want to reset all data? This action cannot be undone.
                </DialogDescription>
              </DialogHeader>
              <DialogFooter className="flex flex-row gap-2 w-full">
                <Button
                  variant="secondary"
                  onClick={() => setShowResetDialog(false)}
                  className="flex-1"
                >
                  Cancel
                </Button>
                <Button variant="default" onClick={resetApp} className="flex-1">
                  Reset
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>

          <AnimatePresence>
            {participants.map((participant, index) => (
              <motion.div
                key={participant.id}
                initial={{ opacity: 0, y: 20 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -20 }}
                transition={{ duration: 0.2, delay: index * 0.1 }}
              >
                <Card className="shadow-lg">
                  <CardHeader>
                    <div className="flex justify-between items-center">
                      <CardTitle>{participant.name}</CardTitle>
                    </div>
                    <div className="space-y-2">
                      <div className="text-sm text-muted-foreground flex justify-between items-center">
                        <span>
                          Points Available: {participant.pointsAvailable} /{" "}
                          {Math.floor(totalPoints / participants.length)}
                        </span>
                        <span
                          className={`text-xs ${
                            participant.pointsAvailable < 0
                              ? "text-destructive font-medium"
                              : ""
                          }`}
                        >
                          {(
                            (participant.pointsAvailable /
                              (totalPoints / participants.length)) *
                            100
                          ).toFixed(1)}
                          %
                        </span>
                      </div>
                      <Progress
                        value={
                          100 -
                          (participant.pointsAvailable /
                            (totalPoints / participants.length)) *
                            100
                        }
                        className={`h-2 ${
                          participant.pointsAvailable < 0
                            ? "[&>div]:bg-destructive"
                            : ""
                        }`}
                      />
                    </div>
                  </CardHeader>
                  <CardContent className="pt-0">
                    <div className="space-y-2">
                      <AnimatePresence mode="popLayout">
                        {participant.prizes.map((prize) => (
                          <motion.div
                            key={`${participant.id}-${prize.id}`}
                            layout
                            initial={{ opacity: 0, height: 0 }}
                            animate={{ opacity: 1, height: "auto" }}
                            exit={{ opacity: 0, height: 0 }}
                            transition={{
                              type: "spring",
                              stiffness: 500,
                              damping: 30,
                              opacity: { duration: 0.2 },
                            }}
                            className="overflow-hidden"
                          >
                            <Card className="bg-secondary">
                              <CardContent className="flex justify-between items-center p-2">
                                {editingPrize?.prizeId === prize.id ? (
                                  <div className="flex-1 flex gap-4 items-center">
                                    <div className="w-1/2">
                                      <Input
                                        value={editingPrize.name}
                                        onChange={(e) =>
                                          setEditingPrize({ ...editingPrize, name: e.target.value })
                                        }
                                        className="h-8"
                                      />
                                    </div>
                                    <div className="w-1/4">
                                      <Input
                                        type="text"
                                        inputMode="numeric"
                                        value={editingPrize.points}
                                        onChange={(e) =>
                                          setEditingPrize({ ...editingPrize, points: e.target.value })
                                        }
                                        className="h-8"
                                      />
                                    </div>
                                    <div className="flex items-center gap-2">
                                      <Button
                                        variant="outline"
                                        size="icon"
                                        className="h-8 w-8"
                                        onClick={() => {
                                          const current = parseInt(editingPrize.quantity) || 1;
                                          setEditingPrize({
                                            ...editingPrize,
                                            quantity: Math.max(1, current - 1).toString(),
                                          });
                                        }}
                                        disabled={parseInt(editingPrize.quantity) <= 1}
                                      >
                                        <Minus className="h-3 w-3" />
                                      </Button>
                                      <span className="w-4 text-center">{editingPrize.quantity}</span>
                                      <Button
                                        variant="outline"
                                        size="icon"
                                        className="h-8 w-8"
                                        onClick={() => {
                                          const current = parseInt(editingPrize.quantity) || 1;
                                          setEditingPrize({
                                            ...editingPrize,
                                            quantity: (current + 1).toString(),
                                          });
                                        }}
                                      >
                                        <Plus className="h-3 w-3" />
                                      </Button>
                                    </div>
                                  </div>
                                ) : (
                                  <div className="flex gap-2 items-baseline">
                                    <div className="font-medium text-md">{prize.name}</div>
                                    <div className="text-sm text-muted-foreground">
                                      {prize.quantity > 1 ? `${prize.quantity}x ` : ''}{prize.points} points
                                      {prize.quantity > 1 ? ` (${prize.points * prize.quantity} total)` : ''}
                                    </div>
                                  </div>
                                )}
                                <div className="flex gap-1">
                                  <Button
                                    variant="ghost"
                                    size="icon"
                                    onClick={() => {
                                      setEditingParticipantId(participant.id);
                                      setEditingPrize({
                                        participantId: participant.id,
                                        prizeId: prize.id,
                                        name: prize.name,
                                        points: prize.points.toString(),
                                        quantity: prize.quantity.toString(),
                                      });
                                      setNewPrizeName(prize.name);
                                      setNewPrizePoints(prize.points.toString());
                                      setNewPrizeQuantity(prize.quantity.toString());
                                    }}
                                    className="h-8 w-8"
                                  >
                                    <Pencil className="h-4 w-4" />
                                  </Button>
                                  <Button
                                    variant="ghost"
                                    size="icon"
                                    onClick={() => removePrize(participant.id, prize.id)}
                                    className="h-8 w-8"
                                  >
                                    <Trash2 className="h-4 w-4" />
                                  </Button>
                                </div>
                              </CardContent>
                            </Card>
                          </motion.div>
                        ))}
                      </AnimatePresence>

                      {!participant.prizes.length && (
                        <Alert variant="default" className="bg-muted">
                          <AlertDescription className="text-center">
                            No prizes added yet
                          </AlertDescription>
                        </Alert>
                      )}

                      <Dialog
                        open={editingParticipantId === participant.id}
                        onOpenChange={(open) => {
                          if (!open) {
                            setEditingParticipantId(null);
                            setEditingPrize(null);
                            setNewPrizeName("");
                            setNewPrizePoints("");
                            setNewPrizeQuantity("1");
                          }
                        }}
                      >
                        <DialogTrigger asChild>
                          <Button
                            className="w-full"
                            variant="outline"
                            onClick={() =>
                              setEditingParticipantId(participant.id)
                            }
                          >
                            <Plus className="h-4 w-4 mr-2" />
                            Add Prize
                          </Button>
                        </DialogTrigger>
                        <DialogContent>
                          <DialogHeader>
                            <DialogTitle>
                              {editingPrize ? 'Edit' : 'Add'} Prize for {participant.name}
                            </DialogTitle>
                            <DialogDescription>
                              Available Points: {participant.pointsAvailable}
                            </DialogDescription>
                          </DialogHeader>
                          <div className="space-y-4 py-4">
                            <div className="flex gap-4">
                              <div className="w-2/3 space-y-2">
                                <Label htmlFor="prize-name">Prize Name</Label>
                                <Input
                                  id="prize-name"
                                  value={newPrizeName}
                                  onChange={(e) =>
                                    setNewPrizeName(e.target.value)
                                  }
                                />
                              </div>
                              <div className="w-1/3 space-y-2">
                                <Label htmlFor="prize-points">Points</Label>
                                <Input
                                  id="prize-points"
                                  type="text"
                                  inputMode="numeric"
                                  value={newPrizePoints}
                                  onChange={(e) =>
                                    setNewPrizePoints(e.target.value)
                                  }
                                />
                              </div>
                            </div>
                            <div>
                              <Label>Quantity</Label>
                              <div className="flex items-center gap-4 mt-2">
                                <Button
                                  variant="outline"
                                  size="icon"
                                  onClick={() => {
                                    const current = parseInt(newPrizeQuantity) || 1;
                                    setNewPrizeQuantity(Math.max(1, current - 1).toString());
                                  }}
                                  disabled={parseInt(newPrizeQuantity) <= 1}
                                >
                                  <Minus className="h-4 w-4" />
                                </Button>
                                <div className="text-xl font-medium w-8 text-center">
                                  {newPrizeQuantity}
                                </div>
                                <Button
                                  variant="outline"
                                  size="icon"
                                  onClick={() => {
                                    const current = parseInt(newPrizeQuantity) || 1;
                                    setNewPrizeQuantity((current + 1).toString());
                                  }}
                                >
                                  <Plus className="h-4 w-4" />
                                </Button>
                              </div>
                            </div>
                          </div>
                          <DialogFooter className="flex flex-row gap-2 w-full ">
                            <Button
                              variant="outline"
                              onClick={() => setEditingParticipantId(null)}
                              className="flex-1"
                            >
                              Cancel
                            </Button>
                            <Button
                              onClick={() => handleAddPrize(participant.id)}
                              disabled={!newPrizeName}
                              className="flex-1"
                            >
                              {editingPrize ? 'Save' : 'Add'} Prize
                            </Button>
                          </DialogFooter>
                        </DialogContent>
                      </Dialog>
                    </div>
                  </CardContent>
                </Card>
              </motion.div>
            ))}
          </AnimatePresence>
        </div>
      </div>
    </>
  );

  switch (stage) {
    case "setup":
      return renderSetupStage();
    case "points":
      return renderPointsStage();
    case "tracking":
      return renderTrackingStage();
    default:
      return null;
  }
};

export default ArcadeTracker;
