"use client";

import * as React from "react";
import Image from "next/image";
import { MessageSquare, X, Loader2, ImagePlus } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Input } from "@/components/ui/input";
import { UserAvatar } from "@/components/ui/user-avatar";
import { DeleteConfirmationAlert } from "@/components/ui/delete-confirmation-alert";
import {
  useAddDealNoteMutation,
  useUpdateDealNoteMutation,
  useDeleteDealNoteMutation,
  useUploadDealNoteImageMutation,
} from "@/api/rtk/deals-api";
import {
  DealNoteComposer,
  getEditableTextFromNote,
  getNoteImageUrls,
  mergeEditedNoteTextWithImages,
  NoteContent,
} from "./deal-note-composer";
import { DealNote } from "./types";

interface DealNotesTabProps {
  dealId: string;
  notes: DealNote[];
  canEditNotes: boolean;
  apiBaseUrl: string;
  isFetching?: boolean;
  isLoading?: boolean;
  /** `modal` fills the dialog body; `inline` keeps the legacy tab height cap. */
  layout?: "inline" | "modal";
}

export function DealNotesTab({
  dealId,
  notes,
  canEditNotes,
  apiBaseUrl,
  isFetching,
  isLoading,
  layout = "inline",
}: DealNotesTabProps) {
  const isModal = layout === "modal";
  const [editingNoteId, setEditingNoteId] = React.useState<string | null>(null);
  const [editingNoteText, setEditingNoteText] = React.useState("");
  const [editingNoteRemainingImageUrls, setEditingNoteRemainingImageUrls] = React.useState<string[] | null>(null);
  const [editingNoteUploadingImage, setEditingNoteUploadingImage] = React.useState(false);
  const [deleteNoteId, setDeleteNoteId] = React.useState<string | null>(null);

  const notesEndRef = React.useRef<HTMLDivElement>(null);
  const editNoteFileInputRef = React.useRef<HTMLInputElement>(null);

  const [addNoteMutation] = useAddDealNoteMutation();
  const [updateNoteMutation, { isLoading: isUpdatingNote }] = useUpdateDealNoteMutation();
  const [deleteNoteMutation, { isLoading: isDeletingNote }] = useDeleteDealNoteMutation();
  const [uploadNoteImage] = useUploadDealNoteImageMutation();

  const handleAddNote = async (content: string) => {
    try {
      await addNoteMutation({ dealId, text: content }).unwrap();
      setTimeout(() => notesEndRef.current?.scrollIntoView({ behavior: "smooth" }), 100);
    } catch (err) {
      toast.error("Failed to add note");
    }
  };

  const handleUpdateNote = async (noteId: string, text: string) => {
    try {
      const finalContent = mergeEditedNoteTextWithImages(text, editingNoteRemainingImageUrls || [], apiBaseUrl);
      await updateNoteMutation({ dealId, noteId, text: finalContent }).unwrap();
      setEditingNoteId(null);
      setEditingNoteRemainingImageUrls(null);
      toast.success("Note updated");
    } catch (err) {
      toast.error("Failed to update note");
    }
  };

  const handleEditNoteAddImage = async (file: File) => {
    setEditingNoteUploadingImage(true);
    try {
      const res = await uploadNoteImage({ dealId, file }).unwrap();
      if (res.url) {
        setEditingNoteRemainingImageUrls((prev) => [...(prev || []), res.url]);
      }
    } catch (err) {
      toast.error("Failed to upload image");
    } finally {
      setEditingNoteUploadingImage(false);
    }
  };

  const handleDeleteNote = async (noteId: string) => {
    try {
      await deleteNoteMutation({ dealId, noteId }).unwrap();
      toast.success("Note deleted successfully");
      setDeleteNoteId(null);
    } catch (err) {
      toast.error("Failed to delete note");
    }
  };

  return (
    <div className={isModal ? "flex min-h-0 flex-1 flex-col" : "flex min-h-[400px] flex-col"}>
      {isFetching && !isLoading ? (
        <div
          className="mb-3 flex items-center gap-2 rounded-lg border border-[#6C63FF]/20 bg-[#6C63FF]/10 px-3 py-2 text-[11px] font-medium tracking-wide text-[#5a52d6] animate-in fade-in duration-300"
          role="status"
          aria-live="polite"
        >
          <span className="relative flex h-2 w-2">
            <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-[#6C63FF] opacity-40" />
            <span className="relative inline-flex h-2 w-2 rounded-full bg-[#6C63FF]" />
          </span>
          Syncing latest notes…
        </div>
      ) : null}

      <div
        className={
          isModal
            ? "min-h-0 flex-1 space-y-6 overflow-y-auto pb-4 pr-1 custom-scrollbar"
            : "max-h-[400px] min-h-0 flex-1 space-y-6 overflow-y-auto pb-6 pr-1 custom-scrollbar"
        }
      >
        {notes?.length ? (
          notes.map((note) => (
            <div key={note.id} className="flex gap-4 group animate-in fade-in slide-in-from-bottom-2">
              <UserAvatar avatar={note.author?.profile?.avatar} name={note.author?.name} size="md" />
              <div className="flex-1">
                <div className="bg-gray-50 rounded-2xl p-4 border border-gray-100 group-hover:bg-white transition-colors">
                  <div className="flex justify-between mb-2">
                    <span className="text-sm font-semibold">{note.author?.name}</span>
                    <span className="text-[10px] text-gray-400">
                      {new Date(note.createdAt).toLocaleString(undefined, { hour12: true })}
                    </span>
                  </div>
                  {editingNoteId === note.id ? (
                    <div className="space-y-4">
                      <Textarea
                        className="min-h-[100px] text-sm bg-white border-gray-200 focus:ring-[#6C63FF]/20"
                        value={editingNoteText}
                        onChange={(e) => setEditingNoteText(e.target.value)}
                        autoFocus
                        placeholder="Note text... (optional if images present)"
                      />

                      {editingNoteRemainingImageUrls && editingNoteRemainingImageUrls.length > 0 && (
                        <div className="flex flex-wrap gap-2 p-2 bg-white/50 rounded-lg border border-dashed border-gray-200">
                          {editingNoteRemainingImageUrls.map((url, idx) => (
                            <div key={`${url}-${idx}`} className="relative group/edit-img">
                              <div className="size-16 rounded-md overflow-hidden border border-gray-200">
                                <Image src={url} alt="" fill className="object-cover" />
                              </div>
                              <button
                                onClick={() =>
                                  setEditingNoteRemainingImageUrls(
                                    (prev) => prev?.filter((_, i) => i !== idx) || null
                                  )
                                }
                                className="absolute -top-1.5 -right-1.5 size-5 rounded-full bg-red-500 text-white flex items-center justify-center shadow-sm opacity-0 group-hover/edit-img:opacity-100 transition-opacity"
                              >
                                <X size={10} />
                              </button>
                            </div>
                          ))}
                          <button
                            onClick={() => editNoteFileInputRef.current?.click()}
                            className="size-16 rounded-md border-2 border-dashed border-gray-200 flex flex-col items-center justify-center text-gray-400 hover:text-[#6C63FF] hover:border-[#6C63FF]/50 transition-all gap-1"
                          >
                            {editingNoteUploadingImage ? (
                              <Loader2 size={14} className="animate-spin" />
                            ) : (
                              <ImagePlus size={14} />
                            )}
                            <span className="text-[9px] font-bold uppercase">Add</span>
                          </button>
                        </div>
                      )}

                      <Input
                        type="file"
                        ref={editNoteFileInputRef}
                        className="hidden"
                        accept="image/*"
                        onChange={(e) => {
                          const file = e.target.files?.[0];
                          if (file) handleEditNoteAddImage(file);
                          e.target.value = "";
                        }}
                      />

                      <div className="flex gap-2">
                        <Button
                          size="sm"
                          className="bg-[#6C63FF] hover:bg-[#5a52e0]"
                          onClick={() => handleUpdateNote(note.id, editingNoteText)}
                          disabled={
                            isUpdatingNote ||
                            (!editingNoteText.trim() &&
                              (!editingNoteRemainingImageUrls || editingNoteRemainingImageUrls.length === 0))
                          }
                        >
                          {isUpdatingNote ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
                          Save Changes
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            setEditingNoteId(null);
                            setEditingNoteRemainingImageUrls(null);
                          }}
                        >
                          Cancel
                        </Button>
                      </div>
                    </div>
                  ) : (
                    <NoteContent text={note.text} apiBaseUrl={apiBaseUrl} imageUrl={note.Media?.url} />
                  )}
                </div>
                {!editingNoteId && canEditNotes ? (
                  <div className="flex gap-4 mt-2 ml-2 opacity-0 group-hover:opacity-100 transition-opacity">
                    <button
                      onClick={() => {
                        setEditingNoteId(note.id);
                        setEditingNoteText(getEditableTextFromNote(note.text));
                        setEditingNoteRemainingImageUrls(getNoteImageUrls(note.text, apiBaseUrl));
                      }}
                      className="text-[11px] font-semibold text-gray-400 hover:text-[#6C63FF]"
                    >
                      Edit
                    </button>
                    <button
                      onClick={() => setDeleteNoteId(note.id)}
                      className="text-[11px] font-semibold text-gray-400 hover:text-red-500"
                    >
                      Delete
                    </button>
                  </div>
                ) : null}
              </div>
            </div>
          ))
        ) : (
          <div className="flex flex-col items-center justify-center py-20 opacity-30">
            <MessageSquare size={48} />
            <p className="mt-2 text-sm font-medium">No notes yet</p>
          </div>
        )}
        <div ref={notesEndRef} />
      </div>

      <div className="sticky bottom-0 pt-4">
        <DealNoteComposer
          dealId={dealId}
          apiBaseUrl={apiBaseUrl}
          disabled={!canEditNotes}
          onSend={handleAddNote}
          uploadImage={async (did, file) => uploadNoteImage({ dealId: did, file }).unwrap()}
        />
      </div>

      <DeleteConfirmationAlert
        open={!!deleteNoteId}
        onOpenChange={(o) => !o && setDeleteNoteId(null)}
        onConfirm={async () => {
          if (deleteNoteId) await handleDeleteNote(deleteNoteId);
        }}
        title="Delete Note"
        description="Permanently remove this note."
        isLoading={isDeletingNote}
      />
    </div>
  );
}
