"use client";

import {
  faAlignCenter,
  faAlignJustify,
  faAlignLeft,
  faAlignRight,
  faBold,
  faEraser,
  faHeading,
  faHighlighter,
  faImage,
  faItalic,
  faLink,
  faListOl,
  faListUl,
  faRotateLeft,
  faRotateRight,
  faTimes,
  faUnderline,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import CharacterCount from "@tiptap/extension-character-count";
import Color from "@tiptap/extension-color";
import Highlight from "@tiptap/extension-highlight";
import TiptapImage from "@tiptap/extension-image";
import Link from "@tiptap/extension-link";
import Placeholder from "@tiptap/extension-placeholder";
import TextAlign from "@tiptap/extension-text-align";
import { TextStyle } from "@tiptap/extension-text-style";
import Underline from "@tiptap/extension-underline";
import { EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Image from "next/image";
import { useEffect, useState } from "react";
import ImageUpload from "@/components/ui/ImageUpload";
import AdminInput from "@/components/admin/AdminInput";
import AdminTextarea from "@/components/admin/AdminTextarea";
import AdminButton from "@/components/admin/AdminButton";
import AdminSection from "@/components/admin/AdminSection";
import { adminFetch } from "@/lib/adminFetch";

interface ProjectWithFiles {
  id?: number;
  name: string;
  description: string;
  shortDescription?: string;
  coverImage: string | File;
  galleryImages: (string | File)[];
}

interface ProjectFormProps {
  initialProject?: ProjectWithFiles;
  onSave: (project: ProjectWithFiles) => void;
  onCancel: () => void;
  isSaving: boolean;
}

export default function ProjectForm({
  initialProject,
  onSave,
  onCancel,
  isSaving,
}: ProjectFormProps) {
  const [project, setProject] = useState<ProjectWithFiles>(
    initialProject || {
      name: "",
      description: "",
      shortDescription: "",
      coverImage: "",
      galleryImages: [],
    },
  );
  const [previewImage, setPreviewImage] = useState<string | null>(null);
  const [previewGallery, setPreviewGallery] = useState<string[]>([]);

  const editor = useEditor({
    immediatelyRender: false,
    extensions: [
      StarterKit,
      Underline,
      Link.configure({ openOnClick: true, HTMLAttributes: { class: "text-indigo-400 underline" } }),
      TiptapImage.configure({ inline: false, HTMLAttributes: { class: "rounded" } }),
      TextAlign.configure({ types: ["heading", "paragraph"] }),
      TextStyle,
      Color,
      Highlight.configure({ multicolor: true }),
      Placeholder.configure({ placeholder: "Write a compelling project description..." }),
      CharacterCount.configure(),
    ],
    content: project.description || "",
    editorProps: {
      attributes: {
        class:
          "prose prose-invert max-w-none min-h-[220px] p-4 rounded-lg border border-slate-800 bg-slate-950 focus:outline-none focus:border-indigo-500",
      },
    },
    onUpdate: ({ editor }) => {
      setProject((prev) => ({ ...prev, description: editor.getHTML() }));
    },
  });

  useEffect(() => {
    if (initialProject) {
      setProject(initialProject);
      setPreviewImage(null);
      setPreviewGallery([]);
      if (editor) {
        editor.commands.setContent(initialProject.description || "");
      }
    }
  }, [initialProject, editor]);

  const handleCoverImageChange = async (file: File | File[]) => {
    const selectedFile = Array.isArray(file) ? file[0] : file;
    if (!selectedFile) return;
    setProject({ ...project, coverImage: selectedFile });
    setPreviewImage(URL.createObjectURL(selectedFile));
  };

  const handleGalleryImagesChange = async (files: File | File[] | FileList) => {
    const fileArray = Array.isArray(files)
      ? files
      : files instanceof FileList
        ? Array.from(files)
        : [files];
    setProject({ ...project, galleryImages: [...project.galleryImages, ...fileArray] });
    setPreviewGallery([
      ...previewGallery,
      ...fileArray.map((file) => URL.createObjectURL(file)),
    ]);
  };

  const handleDeleteGalleryImage = (index: number) => {
    setProject({
      ...project,
      galleryImages: project.galleryImages.filter((_, i) => i !== index),
    });
    setPreviewGallery(previewGallery.filter((_, i) => i !== index));
  };

  useEffect(() => {
    return () => {
      if (previewImage) URL.revokeObjectURL(previewImage);
      previewGallery.forEach((url) => URL.revokeObjectURL(url));
    };
  }, [previewImage, previewGallery]);

  const toolbarButtonClass = (isActive: boolean) =>
    `inline-flex h-8 min-w-8 items-center justify-center px-2 text-xs rounded-md border transition-colors ${
      isActive
        ? "bg-indigo-500 text-white border-indigo-500"
        : "bg-slate-900 border-slate-800 text-slate-300 hover:bg-slate-800 hover:text-slate-100"
    }`;

  return (
    <div className="space-y-6">
      <AdminSection title="Project Details">
        <AdminInput
          label="Project Name"
          placeholder="Enter project name"
          value={project.name}
          onChange={(e) => setProject({ ...project, name: e.target.value })}
          required
        />
        <AdminTextarea
          label="Short Description"
          placeholder="Brief description shown on project cards"
          value={project.shortDescription || ""}
          onChange={(e) => setProject({ ...project, shortDescription: e.target.value })}
          rows={2}
          helperText="This appears on project cards and listings"
        />
      </AdminSection>

      <AdminSection title="Full Description">
        <div className="mb-3 flex flex-wrap gap-2">
          <button
            type="button"
            title="Bold"
            onClick={() => editor?.chain().focus().toggleBold().run()}
            className={toolbarButtonClass(editor?.isActive("bold") ?? false)}
          >
            <FontAwesomeIcon icon={faBold} />
          </button>
          <button
            type="button"
            title="Italic"
            onClick={() => editor?.chain().focus().toggleItalic().run()}
            className={toolbarButtonClass(editor?.isActive("italic") ?? false)}
          >
            <FontAwesomeIcon icon={faItalic} />
          </button>
          <button
            type="button"
            title="Underline"
            onClick={() => editor?.chain().focus().toggleUnderline().run()}
            className={toolbarButtonClass(editor?.isActive("underline") ?? false)}
          >
            <FontAwesomeIcon icon={faUnderline} />
          </button>
          <button
            type="button"
            title="Highlight"
            onClick={() => editor?.chain().focus().toggleHighlight().run()}
            className={toolbarButtonClass(editor?.isActive("highlight") ?? false)}
          >
            <FontAwesomeIcon icon={faHighlighter} />
          </button>
          <div className="mx-1 h-6 w-px bg-slate-800" />
          <button
            type="button"
            title="Align left"
            onClick={() => editor?.chain().focus().setTextAlign("left").run()}
            className={toolbarButtonClass(editor?.isActive({ textAlign: "left" }) ?? false)}
          >
            <FontAwesomeIcon icon={faAlignLeft} />
          </button>
          <button
            type="button"
            title="Align center"
            onClick={() => editor?.chain().focus().setTextAlign("center").run()}
            className={toolbarButtonClass(editor?.isActive({ textAlign: "center" }) ?? false)}
          >
            <FontAwesomeIcon icon={faAlignCenter} />
          </button>
          <button
            type="button"
            title="Align right"
            onClick={() => editor?.chain().focus().setTextAlign("right").run()}
            className={toolbarButtonClass(editor?.isActive({ textAlign: "right" }) ?? false)}
          >
            <FontAwesomeIcon icon={faAlignRight} />
          </button>
          <button
            type="button"
            title="Justify"
            onClick={() => editor?.chain().focus().setTextAlign("justify").run()}
            className={toolbarButtonClass(editor?.isActive({ textAlign: "justify" }) ?? false)}
          >
            <FontAwesomeIcon icon={faAlignJustify} />
          </button>
          <div className="mx-1 h-6 w-px bg-slate-800" />
          <button
            type="button"
            title="Bullet list"
            onClick={() => editor?.chain().focus().toggleBulletList().run()}
            className={toolbarButtonClass(editor?.isActive("bulletList") ?? false)}
          >
            <FontAwesomeIcon icon={faListUl} />
          </button>
          <button
            type="button"
            title="Ordered list"
            onClick={() => editor?.chain().focus().toggleOrderedList().run()}
            className={toolbarButtonClass(editor?.isActive("orderedList") ?? false)}
          >
            <FontAwesomeIcon icon={faListOl} />
          </button>
          <button
            type="button"
            title="H2"
            onClick={() => editor?.chain().focus().toggleHeading({ level: 2 }).run()}
            className={toolbarButtonClass(editor?.isActive("heading", { level: 2 }) ?? false)}
          >
            <FontAwesomeIcon icon={faHeading} />2
          </button>
          <button
            type="button"
            title="H3"
            onClick={() => editor?.chain().focus().toggleHeading({ level: 3 }).run()}
            className={toolbarButtonClass(editor?.isActive("heading", { level: 3 }) ?? false)}
          >
            <FontAwesomeIcon icon={faHeading} />3
          </button>
          <div className="mx-1 h-6 w-px bg-slate-800" />
          <button
            type="button"
            title="Insert link"
            onClick={() => {
              const url = prompt("Enter URL");
              if (url) editor?.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
            }}
            className={toolbarButtonClass(false)}
          >
            <FontAwesomeIcon icon={faLink} />
          </button>
          <button
            type="button"
            title="Insert image"
            onClick={() => {
              const input = document.createElement("input");
              input.type = "file";
              input.accept = "image/*";
              input.onchange = async () => {
                const file = input.files?.[0];
                if (!file) return;
                const form = new FormData();
                form.append("file", file);
                const res = await adminFetch("/api/upload", { method: "POST", body: form });
                if (!res.ok) return;
                const { url } = await res.json();
                editor
                  ?.chain()
                  .focus()
                  .setImage({ src: url.replace("/uploads/", "/api/uploads/") })
                  .run();
              };
              input.click();
            }}
            className={toolbarButtonClass(false)}
          >
            <FontAwesomeIcon icon={faImage} />
          </button>
          <div className="mx-1 h-6 w-px bg-slate-800" />
          <button
            type="button"
            title="Undo"
            onClick={() => editor?.chain().focus().undo().run()}
            className={toolbarButtonClass(false)}
          >
            <FontAwesomeIcon icon={faRotateLeft} />
          </button>
          <button
            type="button"
            title="Redo"
            onClick={() => editor?.chain().focus().redo().run()}
            className={toolbarButtonClass(false)}
          >
            <FontAwesomeIcon icon={faRotateRight} />
          </button>
          <button
            type="button"
            title="Clear"
            onClick={() => editor?.chain().focus().unsetAllMarks().clearNodes().run()}
            className={toolbarButtonClass(false)}
          >
            <FontAwesomeIcon icon={faEraser} />
          </button>
        </div>
        <EditorContent editor={editor} />
        <div className="mt-2 text-xs text-slate-500">
          {editor?.storage.characterCount?.characters()} characters
        </div>
      </AdminSection>

      <AdminSection title="Cover Image">
        <ImageUpload
          onImageUpload={handleCoverImageChange}
          currentImage={previewImage || (typeof project.coverImage === "string" ? project.coverImage : null)}
          className="w-full"
        />
      </AdminSection>

      <AdminSection title="Gallery Images">
        <div className="rounded-lg border-2 border-dashed border-slate-800 bg-slate-900/60 p-4">
          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 mb-4">
            {project.galleryImages
              .filter((img) => (typeof img === "string" ? !!img : true))
              .map((image, index) => {
                const imageUrl =
                  typeof image === "string"
                    ? image.replace("/uploads/", "/api/uploads/")
                    : previewGallery[index] || URL.createObjectURL(image as File);
                return (
                  <div
                    key={index}
                    className="relative group w-full aspect-square overflow-hidden rounded-lg shadow"
                  >
                    {imageUrl && (
                      <Image
                        src={imageUrl}
                        alt={`Gallery ${index + 1}`}
                        fill
                        className="object-cover rounded-lg transition-transform duration-200 group-hover:scale-105"
                      />
                    )}
                    <button
                      type="button"
                      onClick={() => handleDeleteGalleryImage(index)}
                      className="absolute inset-0 flex items-center justify-center bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity z-10"
                    >
                      <FontAwesomeIcon icon={faTimes} className="text-2xl text-white" />
                    </button>
                  </div>
                );
              })}
            <label className="group relative flex aspect-square w-full cursor-pointer items-center justify-center rounded-lg border-2 border-dashed border-slate-700 text-slate-400 transition-colors hover:border-indigo-500 hover:bg-slate-800/40 hover:text-indigo-400">
              <span className="text-4xl">+</span>
              <input
                type="file"
                multiple
                accept="image/*"
                className="absolute inset-0 opacity-0 cursor-pointer"
                onChange={(e) => {
                  if (e.target.files) handleGalleryImagesChange(e.target.files);
                }}
              />
            </label>
          </div>
        </div>
      </AdminSection>

      <div className="flex justify-end gap-2 border-t border-slate-800 pt-4">
        <AdminButton variant="secondary" onClick={onCancel} disabled={isSaving}>
          Cancel
        </AdminButton>
        <AdminButton variant="primary" onClick={() => onSave(project)} isLoading={isSaving}>
          {project.id ? "Save changes" : "Add project"}
        </AdminButton>
      </div>
    </div>
  );
}
