import { ImageCropDialog } from "@ui/components/ImageCropDialog";
import { toast } from "@xtablo/shared";
import { Avatar, AvatarFallback, AvatarImage } from "@xtablo/ui/components/avatar";
import { Button } from "@xtablo/ui/components/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@xtablo/ui/components/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@xtablo/ui/components/dialog";
import { Input } from "@xtablo/ui/components/input";
import { Label } from "@xtablo/ui/components/label";
import { Switch } from "@xtablo/ui/components/switch";
import { Textarea } from "@xtablo/ui/components/textarea";
import { TypographyH3, TypographyMuted, TypographySmall } from "@xtablo/ui/components/typography";
import { CameraIcon, CookieIcon, Loader2Icon, Trash2Icon, UploadIcon } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { LanguageSelector } from "../components/LanguageSelector";
import { SubscriptionCard } from "../components/SubscriptionCard";
import { useIntroduction } from "../hooks/intros";
import {
  useInviteOrganizationUser,
  useOrganization,
  useRemoveOrganizationMember,
  useUpdateOrganization,
} from "../hooks/organization";
import { useRemoveAvatar, useUpdateProfile, useUploadAvatar } from "../hooks/profile";
import { useCookieConsent } from "../hooks/useCookieConsent";
import { useUser } from "../providers/UserStoreProvider";

export default function SettingsPage() {
  const user = useUser();
  const { t, i18n } = useTranslation(["settings", "common"]);
  const {
    introduction,
    updateIntroduction,
    setDraftIntroduction,
    isPending: updateIntroductionPending,
  } = useIntroduction();
  const { mutate: updateProfile, isPending: updateProfilePending } = useUpdateProfile();
  const { mutate: uploadAvatar } = useUploadAvatar();
  const { mutateAsync: removeAvatar, isPending: removeAvatarPending } = useRemoveAvatar();
  const { preferences, saveConsent } = useCookieConsent();
  const { data: organizationData, isLoading: organizationLoading } = useOrganization();
  const { mutate: updateOrganization, isPending: updateOrganizationPending } =
    useUpdateOrganization();
  const { mutate: inviteOrganizationUser, isPending: inviteOrganizationUserPending } =
    useInviteOrganizationUser();
  const { mutate: removeOrganizationMember, isPending: removeOrganizationMemberPending } =
    useRemoveOrganizationMember();

  const [firstName, setFirstName] = useState(user?.first_name || "");
  const [lastName, setLastName] = useState(user?.last_name || "");
  const [avatarPreview, setAvatarPreview] = useState<string | null>(user?.avatar_url || null);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [imageToCrop, setImageToCrop] = useState<string | null>(null);
  const [isCropDialogOpen, setIsCropDialogOpen] = useState(false);
  const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false);
  const [organizationName, setOrganizationName] = useState("");
  const [inviteEmail, setInviteEmail] = useState("");
  const fileInputRef = useRef<HTMLInputElement>(null);
  const displayedOrganizationPlan =
    organizationData?.organization?.plan === "annual"
      ? "founder"
      : organizationData?.organization?.plan;
  const invitedByCurrentUser = organizationData?.invites_sent || [];
  const organizationMembers = (organizationData?.members || []).filter(
    (member) => member.id !== user?.id
  );
  const canManageMembers = organizationData?.is_billing_owner ?? false;

  const getDisplayName = (input: {
    first_name?: string | null;
    last_name?: string | null;
    name?: string | null;
    email?: string | null;
  }) => {
    const combinedName = [input.first_name, input.last_name].filter(Boolean).join(" ").trim();
    if (combinedName) {
      return combinedName;
    }

    if (input.name) {
      return input.name;
    }

    return input.email || t("settings:teamInvite.unknownUser");
  };

  const formatDate = (date: string) =>
    new Date(date).toLocaleDateString(i18n.language || undefined, {
      day: "numeric",
      month: "short",
      year: "numeric",
    });

  useEffect(() => {
    if (organizationData?.organization?.name) {
      setOrganizationName(organizationData.organization.name);
    }
  }, [organizationData?.organization?.name]);

  const handleAvatarChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      // Check file size (max 5MB)
      if (file.size > 5 * 1024 * 1024) {
        toast.add({
          title: t("settings:toasts.error"),
          description: t("settings:toasts.fileTooLarge"),
          type: "error",
          position: "top-center",
        });
        return;
      }

      // Check file type
      if (!file.type.startsWith("image/")) {
        toast.add({
          title: t("settings:toasts.error"),
          description: t("settings:toasts.invalidImage"),
          type: "error",
          position: "top-center",
        });
        return;
      }

      // Load image for cropping
      const reader = new FileReader();
      reader.onloadend = () => {
        setImageToCrop(reader.result as string);
        setIsCropDialogOpen(true);
      };
      reader.readAsDataURL(file);
    }
  };

  const handleRemoveAvatarClick = () => {
    setIsDeleteConfirmOpen(true);
  };

  const handleConfirmRemoveAvatar = async () => {
    await removeAvatar();
    setAvatarPreview(null);
    setSelectedFile(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
    setIsDeleteConfirmOpen(false);
  };

  const handleUploadAvatar = () => {
    if (selectedFile) {
      uploadAvatar({ file: selectedFile });
    }
  };

  const handleCropComplete = (croppedImageBlob: Blob) => {
    // Convert blob to File
    const croppedFile = new File([croppedImageBlob], "avatar.jpg", {
      type: "image/jpeg",
    });

    setSelectedFile(croppedFile);

    // Create preview
    const reader = new FileReader();
    reader.onloadend = () => {
      setAvatarPreview(reader.result as string);
    };
    reader.readAsDataURL(croppedImageBlob);

    // Reset file input to allow selecting the same file again
    if (fileInputRef.current) {
      fileInputRef.current.value = "";
    }
  };

  return (
    <div className="min-h-screen bg-background">
      <div className="container max-w-3xl mx-auto py-6 px-4">
        <div className="flex justify-between items-start mb-4">
          <div>
            <TypographyH3>{t("settings:title")}</TypographyH3>
            <TypographyMuted>{t("settings:subtitle")}</TypographyMuted>
          </div>
          <div className="flex items-center gap-2 mt-2">
            <LanguageSelector />
          </div>
        </div>
        <div className="space-y-6 mt-6">
          {/* Avatar Section */}
          <Card>
            <CardHeader>
              <CardTitle>{t("settings:avatar.title")}</CardTitle>
              <CardDescription>{t("settings:avatar.description")}</CardDescription>
            </CardHeader>
            <CardContent>
              <div className="flex items-start gap-6">
                {/* Avatar Preview */}
                <div className="relative group">
                  <Avatar className="w-32 h-32 ring-4 ring-gray-100 dark:ring-gray-800">
                    <AvatarImage src={avatarPreview || undefined} alt="Avatar" />
                    <AvatarFallback className="text-3xl bg-linear-to-br from-purple-500 to-blue-500 text-white">
                      {user?.first_name?.charAt(0).toUpperCase() ||
                        user?.name?.charAt(0).toUpperCase() ||
                        "U"}
                    </AvatarFallback>
                  </Avatar>

                  {imageToCrop && (
                    <div className="absolute inset-0 flex items-center justify-center bg-black/40 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
                      <Button
                        variant="outline"
                        size="icon"
                        onClick={() => setIsCropDialogOpen(true)}
                      >
                        <CameraIcon className="w-4 h-4" />
                      </Button>
                    </div>
                  )}
                </div>

                {/* Upload Controls */}
                <div className="flex-1 space-y-4">
                  <div className="space-y-2">
                    <Label htmlFor="avatar-upload" className="text-sm font-medium">
                      {t("settings:avatar.chooseImage")}
                    </Label>
                    <p className="text-xs text-muted-foreground">{t("settings:avatar.fileInfo")}</p>
                  </div>

                  <Input
                    ref={fileInputRef}
                    id="avatar-upload"
                    type="file"
                    accept="image/*"
                    onChange={handleAvatarChange}
                    hidden
                  />

                  <div className="flex gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => fileInputRef.current?.click()}
                      className="gap-2"
                    >
                      <UploadIcon className="w-4 h-4" />
                      {t("settings:avatar.chooseFile")}
                    </Button>

                    {avatarPreview && (
                      <>
                        {selectedFile && (
                          <Button
                            size="sm"
                            onClick={handleUploadAvatar}
                            className="gap-2 bg-linear-to-r from-purple-500/80 to-blue-500/80 hover:from-purple-500 hover:to-blue-500 dark:from-purple-500/80 dark:to-blue-500/80 dark:hover:from-purple-500 dark:hover:to-blue-500"
                          >
                            <TypographySmall>{t("settings:avatar.saveAvatar")}</TypographySmall>
                          </Button>
                        )}
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={handleRemoveAvatarClick}
                          className="gap-2 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950"
                        >
                          <Trash2Icon className="w-4 h-4" />
                          {t("settings:avatar.delete")}
                        </Button>
                      </>
                    )}
                  </div>

                  {selectedFile && (
                    <p className="text-xs text-green-600 dark:text-green-400">
                      {t("settings:avatar.fileSelected")} {selectedFile.name}
                    </p>
                  )}
                </div>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>{t("settings:personalInfo.title")}</CardTitle>
              <CardDescription>{t("settings:personalInfo.description")}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="firstName">{t("settings:personalInfo.firstName")}</Label>
                  <Input
                    id="firstName"
                    value={firstName}
                    onChange={(e) => setFirstName(e.target.value)}
                    placeholder={t("settings:personalInfo.firstNamePlaceholder")}
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="lastName">{t("settings:personalInfo.lastName")}</Label>
                  <Input
                    id="lastName"
                    value={lastName}
                    onChange={(e) => setLastName(e.target.value)}
                    placeholder={t("settings:personalInfo.lastNamePlaceholder")}
                  />
                </div>
              </div>

              <div className="space-y-2">
                <Label htmlFor="email">{t("settings:personalInfo.email")}</Label>
                <Input
                  id="email"
                  type="email"
                  value={user?.email || ""}
                  disabled
                  className="bg-muted"
                />
                <p className="text-xs text-muted-foreground">
                  {t("settings:personalInfo.emailNotEditable")}
                </p>
              </div>

              <div className="flex justify-end">
                <Button
                  disabled={updateProfilePending}
                  onClick={() => updateProfile({ firstName, lastName })}
                >
                  {updateProfilePending
                    ? t("settings:personalInfo.saving")
                    : t("settings:personalInfo.save")}
                </Button>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>{t("settings:organization.title")}</CardTitle>
              <CardDescription>{t("settings:organization.description")}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-2">
                <Label htmlFor="organizationName">{t("settings:organization.name")}</Label>
                <Input
                  id="organizationName"
                  value={organizationName}
                  onChange={(e) => setOrganizationName(e.target.value)}
                  placeholder={t("settings:organization.namePlaceholder")}
                  disabled={organizationLoading}
                />
                <p className="text-xs text-muted-foreground">
                  {t("settings:organization.currentPlan", {
                    plan: displayedOrganizationPlan || "solo",
                  })}
                </p>
                <p className="text-xs text-muted-foreground">
                  {t("settings:organization.stats", {
                    members: organizationData?.organization?.member_count || 0,
                    tablos: organizationData?.organization?.tablo_count || 0,
                  })}
                </p>
              </div>

              <div className="flex justify-end">
                <Button
                  disabled={updateOrganizationPending || organizationName.trim().length < 2}
                  onClick={() => updateOrganization(organizationName.trim())}
                >
                  {updateOrganizationPending
                    ? t("settings:organization.saving")
                    : t("settings:organization.save")}
                </Button>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>{t("settings:teamInvite.title")}</CardTitle>
              <CardDescription>{t("settings:teamInvite.description")}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-2">
                <Label htmlFor="inviteOrganizationEmail">
                  {t("settings:teamInvite.emailLabel")}
                </Label>
                <Input
                  id="inviteOrganizationEmail"
                  type="email"
                  value={inviteEmail}
                  onChange={(e) => setInviteEmail(e.target.value)}
                  placeholder={t("settings:teamInvite.emailPlaceholder")}
                />
                <p className="text-xs text-muted-foreground">{t("settings:teamInvite.hint")}</p>
              </div>

              <div className="flex justify-end">
                <Button
                  disabled={inviteOrganizationUserPending || !inviteEmail.trim()}
                  onClick={() => {
                    inviteOrganizationUser(inviteEmail.trim());
                    setInviteEmail("");
                  }}
                >
                  {inviteOrganizationUserPending
                    ? t("settings:teamInvite.inviting")
                    : t("settings:teamInvite.invite")}
                </Button>
              </div>

              <div className="space-y-3">
                <p className="text-sm font-medium">{t("settings:teamInvite.invitedByYouTitle")}</p>
                {invitedByCurrentUser.length === 0 ? (
                  <p className="text-xs text-muted-foreground">
                    {t("settings:teamInvite.noInvitesYet")}
                  </p>
                ) : (
                  <div className="space-y-2">
                    {invitedByCurrentUser.map((invite) => {
                      const member = invite.invited_member;
                      const displayName = getDisplayName({
                        first_name: member?.first_name,
                        last_name: member?.last_name,
                        name: member?.name,
                        email: member?.email || invite.invited_email,
                      });

                      return (
                        <div
                          key={invite.id}
                          className="flex items-center justify-between rounded-md border px-3 py-2"
                        >
                          <div className="min-w-0">
                            <p className="text-sm font-medium truncate">{displayName}</p>
                            <p className="text-xs text-muted-foreground truncate">
                              {member?.email || invite.invited_email}
                            </p>
                          </div>
                          <p className="text-xs text-muted-foreground shrink-0 ml-3">
                            {t("settings:teamInvite.invitedOn", {
                              date: formatDate(invite.created_at),
                            })}
                          </p>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>

              <div className="space-y-3">
                <p className="text-sm font-medium">{t("settings:teamInvite.membersTitle")}</p>
                {organizationMembers.length === 0 ? (
                  <p className="text-xs text-muted-foreground">
                    {t("settings:teamInvite.noOtherMembers")}
                  </p>
                ) : (
                  <div className="space-y-2">
                    {organizationMembers.map((member) => (
                      <div
                        key={member.id}
                        className="flex items-center justify-between rounded-md border px-3 py-2"
                      >
                        <div className="min-w-0">
                          <p className="text-sm font-medium truncate">
                            {getDisplayName({
                              first_name: member.first_name,
                              last_name: member.last_name,
                              name: member.name,
                              email: member.email,
                            })}
                          </p>
                          <p className="text-xs text-muted-foreground truncate">{member.email}</p>
                        </div>
                        <div className="flex items-center gap-2 ml-3">
                          <p className="text-xs text-muted-foreground shrink-0">
                            {t("settings:teamInvite.joinedOn", {
                              date: member.created_at
                                ? formatDate(member.created_at)
                                : t("settings:teamInvite.unknownDate"),
                            })}
                          </p>
                          {canManageMembers && (
                            <Button
                              variant="outline"
                              size="sm"
                              disabled={removeOrganizationMemberPending}
                              onClick={() => {
                                const confirmed = window.confirm(
                                  t(
                                    "settings:teamInvite.removeConfirm",
                                    "Retirer ce membre de l'organisation ?"
                                  )
                                );
                                if (!confirmed) return;
                                removeOrganizationMember(member.id);
                              }}
                            >
                              {t("settings:teamInvite.remove", "Retirer")}
                            </Button>
                          )}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </CardContent>
          </Card>

          {/* Subscription Section */}
          <SubscriptionCard />

          <Card>
            <CardHeader>
              <CardTitle>{t("settings:introduction.title")}</CardTitle>
              <CardDescription>{t("settings:introduction.description")}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="introductionEmail">{t("settings:introduction.title")}</Label>
                <Textarea
                  id="introductionEmail"
                  value={introduction?.intro_email || ""}
                  onChange={(e) =>
                    setDraftIntroduction({
                      ...introduction,
                      intro_email: e.target.value,
                    })
                  }
                  placeholder={t("settings:introduction.placeholder")}
                  rows={8}
                  className="resize-none"
                />
                <p className="text-xs text-muted-foreground">
                  {t("settings:introduction.emailDescription")}
                </p>
              </div>

              <div className="flex justify-end">
                <Button
                  disabled={updateIntroductionPending}
                  onClick={() =>
                    updateIntroduction({
                      intro_email: introduction.intro_email,
                    })
                  }
                >
                  {updateIntroductionPending
                    ? t("common:actions.saving")
                    : t("common:buttons.save")}
                </Button>
              </div>
            </CardContent>
          </Card>

          {/* Cookie Preferences Section */}
          <Card>
            <CardHeader>
              <div className="flex items-center gap-2">
                <CookieIcon className="w-5 h-5" />
                <CardTitle>{t("settings:cookies.title")}</CardTitle>
              </div>
              <CardDescription>{t("settings:cookies.description")}</CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-4">
                <div className="flex items-center justify-between p-3 rounded-lg border">
                  <div className="space-y-1 flex-1">
                    <Label className="text-sm font-medium block">
                      {t("settings:cookies.essential.title")}
                    </Label>

                    <TypographySmall className="text-muted-foreground block">
                      {t("settings:cookies.essential.description")}
                    </TypographySmall>
                  </div>
                  <Switch
                    checked={true}
                    disabled
                    aria-label={t("settings:cookies.essential.title")}
                  />
                </div>

                <div className="flex items-center justify-between p-3 rounded-lg border">
                  <div className="space-y-1 flex-1">
                    <Label className="text-sm font-medium block">
                      {t("settings:cookies.analytics.title")}
                    </Label>

                    <TypographySmall className="text-muted-foreground block">
                      {t("settings:cookies.analytics.description")}
                    </TypographySmall>
                  </div>
                  <Switch
                    checked={preferences.analytics}
                    onCheckedChange={(checked) =>
                      saveConsent({ ...preferences, analytics: checked as boolean })
                    }
                    aria-label={t("settings:cookies.analytics.title")}
                  />
                </div>

                {/* <div className="flex items-center justify-between p-3 rounded-lg border">
                  <div className="space-y-1 flex-1">
                    <Label className="text-sm font-medium block">
                      {t("settings:cookies.marketing.title")}
                    </Label>

                    <TypographySmall className="text-muted-foreground block">
                      {t("settings:cookies.marketing.description")}
                    </TypographySmall>
                  </div>
                  <Switch
                    checked={preferences.marketing}
                    onCheckedChange={(checked) =>
                      saveConsent({ ...preferences, marketing: checked as boolean })
                    }
                    aria-label={t("settings:cookies.marketing.title")}
                  />
                </div> */}
              </div>
            </CardContent>
          </Card>
        </div>
      </div>

      {/* Image Crop Dialog */}
      {imageToCrop && (
        <ImageCropDialog
          open={isCropDialogOpen}
          onOpenChange={setIsCropDialogOpen}
          imageSrc={imageToCrop}
          onCropComplete={handleCropComplete}
        />
      )}

      {/* Delete Confirmation Dialog */}
      <Dialog open={isDeleteConfirmOpen} onOpenChange={setIsDeleteConfirmOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t("settings:avatar.deleteTitle")}</DialogTitle>
            <DialogDescription>{t("settings:avatar.deleteDescription")}</DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setIsDeleteConfirmOpen(false)}>
              {t("settings:buttons.cancel")}
            </Button>
            <Button
              variant="outline"
              onClick={handleConfirmRemoveAvatar}
              className="gap-2 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950"
            >
              {removeAvatarPending ? (
                <Loader2Icon className="w-4 h-4 animate-spin" />
              ) : (
                <Trash2Icon className="w-4 h-4" />
              )}
              {removeAvatarPending ? t("settings:avatar.deleting") : t("settings:avatar.delete")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
