import Acordion from "@/components/Acordion";
import { Button } from "@/components/ui/button";
import { useGlobal } from "@/context/global";
import { ConvertJSONToFormData, ServerRequest } from "@/lib/actions";
import { LocaleDate } from "@/lib/utils";
import { NoteStatusMap } from "@/models/projects/notesMap";
import { closeNote } from "@/services/notes/closeNote";
import { fetchClosedNotes } from "@/services/notes/fetchNotes";
import { socket } from "@/socket";
import { faNoteSticky } from "@fortawesome/free-regular-svg-icons";
import {
  faArrowLeft,
  faArrowsRotate,
  faCaretRight,
  faInfoCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useParams } from "next/navigation";
import React from "react";

type Data = ProjectData & { notes: DomainNote[] };

type NotesProps = {
  data: Data;
  setData: React.Dispatch<React.SetStateAction<any>>;
  setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
};

type NoteListProps = {
  notes: DomainNote[];
  handleCloseNote?: (note: DomainNote) => void;
};

function NoteList({ notes, handleCloseNote }: NoteListProps) {
  const params: { lang: string } = useParams();

  const { dict } = useGlobal();

  return (
    <>
      <div className="flex flex-col gap-2">
        {notes.map((note, i) => (
          <div key={i} className="rounded p-1 px-2 hover:bg-neutral-100">
            <Acordion
              icon={faCaretRight}
              items={{
                trigger: (
                  <div className="w-full cursor-pointer text-start">
                    <p>{note.title}</p>
                    <p className="text-xs text-gray-500">
                      {LocaleDate(note.updatedAt, params.lang).long()}
                    </p>
                  </div>
                ),
                content: (
                  <>
                    {note.note}
                    {handleCloseNote && (
                      <div className="mt-2">
                        <Button
                          variant="soft"
                          color="danger"
                          size="xs"
                          onClick={() => handleCloseNote(note)}
                        >
                          {dict.pages.project_files.notes.close_note}
                        </Button>
                      </div>
                    )}
                  </>
                ),
              }}
            />
          </div>
        ))}
      </div>
    </>
  );
}

export default function Notes({ data, setData, setIsOpen }: NotesProps) {
  const { dict } = useGlobal();

  const [closedNotes, setClosedNotes] = React.useState<DomainNote[]>();
  const [isPending, startTransition] = React.useTransition();

  const handleFetchClosedNotes = async () => {
    startTransition(async () => {
      const formData = ConvertJSONToFormData({ id: data.id });

      const result = await ServerRequest<DomainNote[]>(
        fetchClosedNotes(formData),
      );

      if (!result.operation) {
        return;
      }

      setClosedNotes(result.data);
    });
  };

  const handleCloseNote = async (note: DomainNote) => {
    const formData = ConvertJSONToFormData({ id: note.id });

    const result = await ServerRequest(closeNote(formData));

    if (!result.operation) {
      return;
    }

    setData((prev) => {
      const newNotes = [...prev.notes];

      const index = newNotes.findIndex((n) => n.id === note.id);

      return {
        ...prev,
        notes: [...prev.notes.slice(0, index), ...prev.notes.slice(index + 1)],
      };
    });

    if (closedNotes) {
      setClosedNotes((prev) => {
        const newNotes = [...prev];

        const index = newNotes.findIndex((n) => n.id === note.id);

        const newNote = {
          ...note,
          status: NoteStatusMap.CLOSED,
        };

        return [
          ...newNotes.slice(0, index),
          newNote,
          ...newNotes.slice(index + 1),
        ];
      });
    }

    socket.emit("close-note", { domain: data.name });
  };

  React.useEffect(() => {
    return () => {
      setClosedNotes(undefined);
    };
  }, []);

  return (
    <div className="absolute right-0 top-0 h-full w-[300px] max-w-full pb-[2px]">
      <div className="relative flex h-full w-full flex-col gap-2 rounded bg-white p-2 shadow">
        <div className="flex items-center gap-2">
          <Button
            variant="plain"
            color="danger"
            size="xs"
            decorator={faArrowLeft}
            onClick={() => setIsOpen(false)}
            isIcon
          />
          <h2 className="text-lg font-bold">
            {dict.pages.project_files.notes.open_notes}
          </h2>
        </div>
        <NoteList notes={data.notes} handleCloseNote={handleCloseNote} />
        {isPending && (
          <p className="px-2 text-xs">
            <FontAwesomeIcon className="animate-spin" icon={faArrowsRotate} />{" "}
            {dict.pages.project_files.notes.loading_closed}
          </p>
        )}
        {!closedNotes ? (
          <div>
            <Button
              variant="soft"
              color="neutral"
              size="sm"
              decorator={faNoteSticky}
              onClick={handleFetchClosedNotes}
            >
              {dict.pages.project_files.notes.fetch_closed_notes}
            </Button>
          </div>
        ) : closedNotes.length ? (
          <>
            <div className="flex items-center gap-2">
              <h2 className="text-lg font-bold">
                {dict.pages.project_files.notes.closed_notes}
              </h2>
            </div>
            <NoteList notes={closedNotes} />
          </>
        ) : (
          <p className="px-2 text-xs">
            <FontAwesomeIcon icon={faInfoCircle} />{" "}
            {dict.pages.project_files.notes.no_closed_notes_found}
          </p>
        )}
      </div>
    </div>
  );
}
