import { toast } from "@xtablo/shared";
import { Button } from "@xtablo/ui/components/button";
import { Card, CardContent, CardHeader } from "@xtablo/ui/components/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} 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 { TypographyH3, TypographyMuted } from "@xtablo/ui/components/typography";
import {
  ChevronLeftIcon,
  ChevronRightIcon,
  ClockIcon,
  CopyIcon,
  ExternalLinkIcon,
  FileTextIcon,
  PlusIcon,
  SaveIcon,
  SearchXIcon,
  Share2Icon,
  StickyNoteIcon,
  TrashIcon,
} from "lucide-react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { NotesEditor } from "../components/NotesEditor";
import {
  useCreateNote,
  useDeleteNote,
  useNote,
  useNoteSharing,
  useNotes,
  useUpdateNote,
  useUpdateNoteSharing,
} from "../hooks/notes";
import { useIsReadOnlyUser } from "../providers/UserStoreProvider";

const useNoteId = () => {
  const navigate = useNavigate();
  const params = useParams();

  const [noteId, setNoteId] = useState<string | undefined>(params.noteId as string | undefined);
  const updateNoteId = (id: string) => {
    navigate(`/notes/${id}`, { replace: true });
    setNoteId(id);
  };

  const goCreateNote = () => {
    navigate("/notes/create", { replace: true });
    setNoteId(undefined);
  };

  return { noteId, setNoteId: updateNoteId, goCreateNote };
};

export default function NotesPage({ mode }: { mode: "create" | "edit" }) {
  const { t } = useTranslation(["notes", "common"]);
  const { noteId, setNoteId, goCreateNote } = useNoteId();
  const isReadOnly = useIsReadOnlyUser();

  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const [isSidebarVisible, setIsSidebarVisible] = useState(true);
  const [editorKey, setEditorKey] = useState(0);
  const [isShareDialogOpen, setIsShareDialogOpen] = useState(false);

  const { notes, isLoading } = useNotes();
  const { note, isLoading: isNoteLoading } = useNote(noteId);
  const { mutate: createNote, isPending: isCreating } = useCreateNote();
  const { mutate: updateNote, isPending: isUpdating } = useUpdateNote();
  const { mutate: deleteNote, isPending: isDeleting } = useDeleteNote();

  // Sharing hooks
  const { isPublic, isSharedWithAllTablos, isLoading: isSharingLoading } = useNoteSharing(noteId);
  const { mutate: updateSharing, isPending: isSharingUpdating } = useUpdateNoteSharing();

  useEffect(() => {
    if (noteId) {
      const note = notes?.find((note) => note.id === noteId);
      if (note) {
        setTitle(note.title ?? "");
        setContent(note.content ?? "");
        setHasUnsavedChanges(false);
      }
    } else if (mode === "create") {
      setTitle("");
      setContent("");
      setHasUnsavedChanges(false);
    }
    setEditorKey((prev) => prev + 1);
  }, [mode, noteId, notes]);

  // Helper function to format dates in a human-readable way
  const formatRelativeDate = (date: Date): string => {
    const now = new Date();
    const diffInMs = now.getTime() - date.getTime();
    const diffInMinutes = Math.floor(diffInMs / (1000 * 60));
    const diffInHours = Math.floor(diffInMs / (1000 * 60 * 60));
    const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24));

    if (diffInMinutes < 1) return t("justNow", "Just now");
    if (diffInMinutes < 60) return t("minutesAgo", "{{count}}m ago", { count: diffInMinutes });
    if (diffInHours < 24) return t("hoursAgo", "{{count}}h ago", { count: diffInHours });
    if (diffInDays === 0) return t("today", "Today");
    if (diffInDays === 1) return t("yesterday", "Yesterday");
    if (diffInDays < 7) return t("daysAgo", "{{count}} days ago", { count: diffInDays });
    if (diffInDays < 30)
      return t("weeksAgo", "{{count}} weeks ago", { count: Math.floor(diffInDays / 7) });
    if (diffInDays < 365)
      return t("monthsAgo", "{{count}} months ago", { count: Math.floor(diffInDays / 30) });
    return date.toLocaleDateString();
  };

  const handleContentChange = (newContent: string) => {
    setContent(newContent);
    setHasUnsavedChanges(true);
  };

  const handleSave = () => {
    if (isReadOnly) {
      toast.add({
        title: t("common:error", "Error"),
        description:
          "Vous êtes en mode lecture seule. Vous ne pouvez pas créer ou modifier de notes.",
        type: "error",
      });
      return;
    }
    if (!content && !title) {
      toast.add({
        title: t("common:error", "Error"),
        description: t("addContentBeforeSaving"),
        type: "error",
      });
      return;
    }
    const params = {
      onSuccess: () => {
        toast.add({
          title: t("common:success", "Success"),
          description: t("savedSuccessfully"),
          type: "success",
        });
      },
      onError: (error: Error) => {
        toast.add({
          title: t("common:error", "Error"),
          description: `${t("saveFailed")}: ${error.message}`,
          type: "error",
        });
      },
    };
    if (mode === "create") {
      createNote({ title: title || "Untitled Note", content }, params);
    } else {
      updateNote({ id: noteId, title: title || "Untitled Note", content }, params);
    }
  };

  const resetEditor = () => {
    setTitle("");
    setContent("");
    setHasUnsavedChanges(false);
    setEditorKey((prev) => prev + 1);
    goCreateNote();
  };

  const handleNewNote = () => {
    if (isReadOnly) {
      toast.add({
        title: t("common:error", "Error"),
        description: "Vous êtes en mode lecture seule. Vous ne pouvez pas créer de notes.",
        type: "error",
      });
      return;
    }
    if (hasUnsavedChanges) {
      const confirmed = window.confirm(t("unsavedChangesWarning"));
      if (!confirmed) return;
    }
    resetEditor();
  };

  const handleSaveSharing = (isPublic: boolean, isSharedWithAllTablos: boolean) => {
    if (!noteId) {
      toast.add({
        title: t("common:error", "Error"),
        description: t("saveNoteBeforeSharing"),
        type: "error",
      });
      return;
    }

    updateSharing(
      {
        noteId,
        isPublic,
        isSharedWithAllTablos,
      },
      {
        onSuccess: () => {
          toast.add({
            title: t("common:success", "Success"),
            description: t("sharingSettingsUpdated"),
            type: "success",
          });
        },
        onError: (error: Error) => {
          toast.add({
            title: t("common:error", "Error"),
            description: `${t("failedToUpdateSharing")}: ${error.message}`,
            type: "error",
          });
        },
      }
    );
  };

  const handleCopyPublicLink = () => {
    if (!noteId) return;
    const publicUrl = `${window.location.origin}/notes/public/${noteId}`;
    navigator.clipboard.writeText(publicUrl);
    toast.add({
      title: t("common:success", "Success"),
      description: t("publicLinkCopied"),
      type: "success",
    });
  };

  const renderNote = () => {
    if (mode === "edit" && noteId) {
      if (isNoteLoading) {
        return (
          <Card className="flex flex-1 flex-col items-center justify-center overflow-hidden"></Card>
        );
      }
      if (!note) {
        return (
          <Card className="flex flex-1 flex-col items-center justify-center overflow-hidden">
            <div className="flex flex-col items-center gap-4 p-8">
              <div className="rounded-full bg-muted p-6">
                <SearchXIcon className="size-12 text-muted-foreground" />
              </div>
              <div className="space-y-2 text-center">
                <TypographyH3 className="text-lg">
                  {t("noteNotFound", "Note not found")}
                </TypographyH3>
                <TypographyMuted className="text-sm max-w-md">
                  {t(
                    "noteNotFoundDescription",
                    "The note you're looking for doesn't exist or has been deleted"
                  )}
                </TypographyMuted>
              </div>
              <Button
                variant="outline"
                onClick={handleNewNote}
                className="mt-2"
                disabled={isReadOnly}
              >
                <PlusIcon className="mr-2 size-4" />
                {t("createNewNote", "Create a new note")}
              </Button>
            </div>
          </Card>
        );
      }
    }

    return (
      <Card className="flex flex-1 flex-col overflow-hidden">
        <CardHeader className="border-b flex flex-row items-center justify-between">
          <div className="flex flex-1 items-center gap-2">
            <Input
              placeholder={t("noteTitlePlaceholder")}
              value={title}
              onChange={(e) => {
                setTitle(e.target.value);
                setHasUnsavedChanges(true);
              }}
              disabled={isReadOnly}
              className="border-0 text-2xl font-bold focus-visible:ring-0"
            />
            {noteId && (
              <Button
                variant="ghost"
                size="icon"
                onClick={(e) => {
                  e.stopPropagation();
                  deleteNote(noteId, {
                    onSuccess: () => {
                      resetEditor();
                    },
                  });
                }}
                disabled={isDeleting || isReadOnly}
                title={t("deleteNote")}
                className="hover:text-red-500 hover:bg-red-50/10 dark:hover:bg-red-950/10"
              >
                <TrashIcon className="size-4" />
              </Button>
            )}
          </div>
        </CardHeader>
        <CardContent className="flex-1 overflow-y-auto p-0">
          <NotesEditor
            key={editorKey}
            initialContent={note?.content ?? content}
            onChange={handleContentChange}
            readOnly={isReadOnly}
          />
        </CardContent>
      </Card>
    );
  };

  return (
    <div className="flex h-full flex-col gap-6 p-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <FileTextIcon className="size-8 text-primary" />
          <div>
            <TypographyH3>{t("title")}</TypographyH3>
            <TypographyMuted>{t("description")}</TypographyMuted>
          </div>
        </div>
        <div className="flex items-center gap-2">
          {noteId && (
            <Dialog open={isShareDialogOpen} onOpenChange={setIsShareDialogOpen}>
              <DialogTrigger asChild>
                <Button variant="outline">
                  <Share2Icon className="mr-2 size-4" />
                  {t("share")}
                </Button>
              </DialogTrigger>
              <DialogContent className="sm:max-w-md">
                <DialogHeader>
                  <DialogTitle>{t("shareNote")}</DialogTitle>
                  <DialogDescription>{t("shareNoteDescription")}</DialogDescription>
                </DialogHeader>
                <div className="space-y-6 py-4">
                  {/* Public Sharing */}
                  <div className="space-y-4">
                    <div className="flex items-center justify-between">
                      <div className="space-y-0.5">
                        <Label htmlFor="public-toggle" className="text-base font-medium">
                          {t("publicAccess")}
                        </Label>
                        <TypographyMuted className="text-sm">
                          {t("publicAccessDescription")}
                        </TypographyMuted>
                      </div>
                      <Switch
                        id="public-toggle"
                        checked={isPublic}
                        onCheckedChange={(checked) =>
                          handleSaveSharing(checked, isSharedWithAllTablos)
                        }
                        disabled={isSharingLoading || isSharingUpdating}
                      />
                    </div>

                    {isPublic && (
                      <div className="flex items-center gap-2 rounded-md bg-muted p-2">
                        <Input
                          readOnly
                          value={`${window.location.origin}/notes/public/${noteId}`}
                          className="text-xs"
                        />
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={handleCopyPublicLink}
                          title={t("copyLink")}
                        >
                          <CopyIcon className="size-4" />
                        </Button>
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={() =>
                            window.open(
                              `${window.location.origin}/notes/public/${noteId}`,
                              "_blank"
                            )
                          }
                          title={t("openLink")}
                        >
                          <ExternalLinkIcon className="size-4" />
                        </Button>
                      </div>
                    )}
                  </div>

                  {/* Tablo Sharing */}
                  <div className="flex items-center justify-between">
                    <div className="space-y-0.5">
                      <Label htmlFor="tablo-toggle" className="text-base font-medium">
                        {t("shareWithAllTablos")}
                      </Label>
                      <TypographyMuted className="text-sm">
                        {t("shareWithAllTablosDescription")}
                      </TypographyMuted>
                    </div>
                    <Switch
                      id="tablo-toggle"
                      checked={isSharedWithAllTablos}
                      onCheckedChange={(checked) => handleSaveSharing(isPublic, checked)}
                      disabled={isSharingLoading || isSharingUpdating}
                    />
                  </div>
                </div>
                <div className="flex justify-end gap-2">
                  <Button
                    variant="outline"
                    onClick={() => {
                      setIsShareDialogOpen(false);
                    }}
                  >
                    {t("close")}
                  </Button>
                </div>
              </DialogContent>
            </Dialog>
          )}
          <Button
            onClick={handleSave}
            disabled={!hasUnsavedChanges || isCreating || isUpdating || isReadOnly}
          >
            <SaveIcon className="mr-2 size-4" />
            {isCreating ? t("saving") : t("saveNote")}
          </Button>
        </div>
      </div>

      {/* Main Content */}
      <div className="flex flex-1 gap-6 overflow-hidden">
        {/* Toggle Button (shown when sidebar is hidden) */}
        {!isSidebarVisible && (
          <Button
            variant="outline"
            size="icon"
            onClick={() => setIsSidebarVisible(true)}
            className="shrink-0 self-start"
            title={t("showSidebar")}
          >
            <ChevronRightIcon className="size-4" />
          </Button>
        )}

        {/* Sidebar - Notes List */}
        {isSidebarVisible && (
          <Card className="w-72 shrink-0 overflow-hidden transition-all border-r">
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4 border-b">
              <div className="flex items-center gap-2">
                <TypographyH3 className="text-base font-semibold">{t("yourNotes")}</TypographyH3>
              </div>
              <Button
                variant="ghost"
                size="icon"
                onClick={() => setIsSidebarVisible(false)}
                className="size-7 hover:bg-muted"
                title={t("hideSidebar")}
              >
                <ChevronLeftIcon className="size-4" />
              </Button>
            </CardHeader>
            <CardContent className="overflow-y-auto pt-1 px-3 max-h-[calc(100vh-16rem)]">
              {/* New Note Button */}
              <Button
                onClick={handleNewNote}
                disabled={isCreating}
                className="w-full mb-3"
                variant="default"
              >
                <PlusIcon className="mr-2 size-4" />
                {t("newNote")}
              </Button>

              {isLoading ? (
                <div className="space-y-2">
                  {[1, 2, 3].map((i) => (
                    <div key={i} className="rounded-lg border bg-muted/30 p-3 animate-pulse">
                      <div className="h-4 bg-muted rounded w-3/4 mb-2" />
                      <div className="h-3 bg-muted rounded w-1/2" />
                    </div>
                  ))}
                </div>
              ) : notes && notes.length > 0 ? (
                <div className="space-y-1">
                  {notes.map((note) => {
                    const isActive = noteId === note.id;
                    const formattedDate = note.updated_at
                      ? formatRelativeDate(new Date(note.updated_at))
                      : "";

                    return (
                      <button
                        key={note.id}
                        onClick={() => {
                          setNoteId(note.id);
                        }}
                        className={`
                          w-full rounded-lg p-3 text-left transition-all
                          hover:bg-accent hover:shadow-sm
                          ${
                            isActive
                              ? "bg-primary/10 border-2 border-primary/30 shadow-sm"
                              : "border border-border hover:border-primary/20"
                          }
                        `}
                      >
                        <div className="flex items-start gap-2">
                          <div className="flex-1 min-w-0">
                            <div
                              className={`font-medium text-sm truncate ${isActive ? "text-primary" : ""}`}
                            >
                              {note.title || t("untitledNote", "Untitled Note")}
                            </div>
                            <div className="flex items-center gap-1 mt-1">
                              <ClockIcon className="size-3 text-muted-foreground" />
                              <span className="text-xs text-muted-foreground">{formattedDate}</span>
                            </div>
                          </div>
                        </div>
                      </button>
                    );
                  })}
                </div>
              ) : (
                <div className="flex flex-col items-center justify-center p-8 text-center">
                  <div className="rounded-full bg-muted p-4 mb-3">
                    <StickyNoteIcon className="size-8 text-muted-foreground" />
                  </div>
                  <TypographyMuted className="text-sm mb-2 font-medium">
                    {t("noNotes")}
                  </TypographyMuted>
                  <TypographyMuted className="text-xs">
                    {t("clickNewNoteToStart", "Click 'New Note' to get started")}
                  </TypographyMuted>
                </div>
              )}
            </CardContent>
          </Card>
        )}

        {/* Editor */}
        {renderNote()}
      </div>
    </div>
  );
}
