import { Moon, Palette, Save, Sun, Undo } from "lucide-react";
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
} from "~/components/ui/card";
import { Label } from "~/components/ui/label";
import {
  cn,
  colors,
  DEFAULT_COLOR,
  DEFAULT_EMOJI,
  getColorClass,
  getSubjectColor,
  getSubjectEmoji,
} from "~/lib/utils";
import { Badge } from "../ui/badge";
import { Button } from "../ui/button";
import { Separator } from "../ui/separator";
import { updateUserPreferences, useSubjects, type User } from "~/lib/api";
import EmojiInput from "./emoji-input";
import { useState } from "react";
import { toast } from "sonner";
import { useQueryClient } from "@tanstack/react-query";
import { useDisplayedTheme } from "../theme-provider";

export default function Preferences({ user }: { user: User }) {
  const [preferences, setPreferences] = useState(user.preferences || []);
  const [unsavedChanges, setUnsavedChanges] = useState(false);
  const { theme, setTheme } = useDisplayedTheme();
  const queryClient = useQueryClient();

  // TODO: Add a loading state and error handling
  const { subjects, isLoading, isError } = useSubjects();

  const resetPreferences = () => {
    setPreferences(user.preferences || []);
    setUnsavedChanges(false);
  };

  const setPref = (subjectName: string, key: string, value: string) => {
    const existingPreference = preferences.find((p) => p.name === subjectName);
    const updatedPreferences = existingPreference
      ? preferences.map((p) =>
          p.name === subjectName ? { ...p, [key]: value } : p
        )
      : [
          ...preferences,
          Object.assign(
            { name: subjectName, emoji: DEFAULT_EMOJI, color: DEFAULT_COLOR },
            {
              name: subjectName,
              [key]: value,
            }
          ),
        ];
    if (!unsavedChanges) {
      toast("Vos changements n'ont pas été sauvegardés", {
        description:
          "N'oubliez pas de sauvegarder vos préférences en bas de la page.",
        duration: 3000,
      });
      setUnsavedChanges(true);
    }
    setPreferences(updatedPreferences);
  };

  function savePreferences() {
    updateUserPreferences(
      // Filter out any incomplete preferences
      preferences.filter((p) => p.name && p.emoji && p.color)
    )
      .then(() => {
        // Invalidate the user query to refresh the data
        queryClient.removeQueries({ queryKey: ["user"] });

        toast.success("Vos préférences ont été sauvegardé avec succès !");
        setUnsavedChanges(false);
      })
      .catch((error) => {
        console.error(
          "Erreur lors de la sauvegarde de vos préférences :",
          error
        );
        toast.error("Échec de la sauvegarde. Veuillez réessayer.");
      });
  }

  return (
    <div className="lg:col-span-2 space-y-6">
      {/* Theme card: darmode light mode */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Moon className="h-5 w-5" />
            Thème
          </CardTitle>
          <CardDescription>
            Personnalisez l'apparence de l'application.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {/* TODO: Save user theme */}
          {/* Theme toggle button */}
          <Button
            variant="default"
            size="sm"
            className="w-full"
            onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
          >
            {theme === "dark" ? (
              <>
                <Sun className="mr-2 h-4 w-4" />
                <span>Activer le mode clair</span>
              </>
            ) : (
              <>
                <Moon className="mr-2 h-4 w-4" />
                <span>Activer le mode sombre</span>
              </>
            )}
          </Button>
        </CardContent>
      </Card>

      {/* Subject Customization Section */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Palette className="h-5 w-5" />
            Personnalisation
          </CardTitle>
          <CardDescription>
            Choisissez les couleurs et emojis des matières.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          {subjects
            .sort((a, b) => a.localeCompare(b))
            .map((subjectName) => ({
              subjectName,
              subjectEmoji: getSubjectEmoji(subjectName, preferences),
              subjectColor: getSubjectColor(subjectName, preferences),
            }))
            .map(({ subjectName, subjectEmoji, subjectColor }) => (
              <div key={subjectName} className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label className="text-base font-medium truncate">
                    {subjectName}
                  </Label>
                  <Badge
                    className={cn(
                      "px-3 py-1 truncate",
                      getColorClass(subjectColor)
                    )}
                  >
                    {subjectEmoji} {subjectName}
                  </Badge>
                </div>
                {/* Color selector */}
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label>Couleur</Label>
                    <div className="flex flex-wrap gap-2">
                      {colors.map((colorName) => (
                        <button
                          key={colorName}
                          type="button"
                          className={cn(
                            "w-4 h-4 rounded-full border",
                            subjectColor === colorName
                              ? "ring-2 ring-offset-2 ring-primary"
                              : "ring-0",
                            getColorClass(colorName)
                          )}
                          onClick={() =>
                            setPref(subjectName, "color", colorName)
                          }
                          title={colorName}
                        />
                      ))}
                    </div>
                  </div>
                  {/* Emoji selector */}
                  <div className="space-y-2">
                    <Label>Emoji</Label>
                    <div className="relative">
                      <EmojiInput
                        type="text"
                        defaultValue={subjectEmoji}
                        onChange={(emoji) =>
                          setPref(subjectName, "emoji", emoji)
                        }
                        className="w-full bg-transparent border border-gray-300 rounded-md px-3 py-2 text-sm text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary"
                      />
                    </div>
                  </div>
                </div>
                <Separator className="my-4" />
              </div>
            ))}
          <Button
            className="w-full"
            onClick={() => savePreferences()}
            disabled={!unsavedChanges}
          >
            <Save className="h-4 w-4 mr-2" />
            Enregistrer vos préférences
          </Button>
          <Button
            variant="destructive"
            className="w-full text-white"
            onClick={resetPreferences}
            disabled={!unsavedChanges}
          >
            <Undo className="h-4 w-4 mr-2" />
            Annuler les modifications en cours
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}
