import { posts, type BlogPost } from "../lib/post";
import { useRef, useState } from "react";
import { useNavigate } from "react-router";
import { useSearchParams } from "react-router";
import {
  ContentState,
  convertFromRaw,
  convertToRaw,
  Editor,
  EditorState,
  RichUtils,
} from "draft-js";
import "draft-js/dist/Draft.css";

export function BlogPostForm({
  post,
  onSubmit,
}: {
  post: BlogPost | null;
  onSubmit: (post: BlogPost) => void;
}) {
  const [postState, setPostState] = useState({
    id: post?.id ?? posts.length,
    title: post?.title ?? "",
    summary: post?.summary ?? "",
    content: post?.content ?? "",
    author: post?.author ?? "",
    datePosted: post?.datePosted ?? new Date().toISOString().split("T")[0],
  });
  const [missing, setMissing] = useState<string[]>([]);
  const [contentState, setContentState] = useState<EditorState>(() => {
    if (post?.content) {
      try {
        const rawContent = JSON.parse(post.content);
        return EditorState.createWithContent(convertFromRaw(rawContent));
      } catch {
        // Fallback to plain text if JSON parsing fails
        return EditorState.createWithContent(
          ContentState.createFromText(post.content),
        );
      }
    }
    return EditorState.createEmpty();
  });

  const editorRef = useRef<Editor>(null);

  const navigate = useNavigate();

  const handleChange = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const { name, value } = event.target;
    setPostState((prevState) => ({ ...prevState, [name]: value }));
  };

  const handleMissing = () => {
    const missingFields = Object.entries(postState)
      .map(([key, value]) => (value === "" ? key : null))
      .filter((key) => key !== null);
    setMissing(missingFields);
  };

  const handleContentChange = (content: EditorState) => {
    setContentState(content);
    const rawContent = convertToRaw(content.getCurrentContent());
    setPostState((prevState) => ({
      ...prevState,
      content: JSON.stringify(rawContent),
    }));
  };

  const handleInlineStyle = (style: string) => {
    setContentState((prevState) =>
      RichUtils.toggleInlineStyle(prevState, style),
    );
  };

  const handleSubmit = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();

    if (
      !postState.title ||
      !postState.summary ||
      !postState.content ||
      !postState.author
    ) {
      handleMissing();
      return;
    }

    onSubmit(postState);
    navigate("/");
  };

  return (
    <form className="flex flex-col gap-4 dark:bg-slate-600 p-10 rounded-lg md:w-4xl w-md">
      <label className="md:grid md:grid-cols-6 flex flex-col w-full gap-2">
        Title:
        <input
          type="text"
          name="title"
          className="border-gray-400 md:col-start-2 md:col-span-5 border rounded h-8 py-1 px-2 w-full"
          value={postState.title}
          onChange={handleChange}
          required
        />
      </label>
      {missing.includes("title") && (
        <p className="text-red-500">Title is required</p>
      )}
      <label className="md:grid md:grid-cols-6 flex flex-col w-full gap-2">
        Summary:
        <textarea
          name="summary"
          className="border-gray-400 md:col-start-2 md:col-span-5 border rounded min-h-16 h-auto py-1 px-2 w-full"
          value={postState.summary}
          onChange={handleChange}
          required
        />
      </label>
      {missing.includes("summary") && (
        <p className="text-red-500">Summary is required</p>
      )}
      <label className="md:grid md:grid-cols-6 flex flex-col w-full gap-2">
        Content:
      </label>
      <div className="md:grid md:grid-cols-6">
        <div className="md:col-start-2 md:col-span-5">
          <div className="flex gap-2 mb-2 border-b pb-2">
            <button
              type="button"
              onMouseDown={(e) => {
                e.preventDefault();
                handleInlineStyle("BOLD");
              }}
              className={`px-3 py-1 border rounded ${
                contentState.getCurrentInlineStyle().has("BOLD")
                  ? "bg-blue-500 text-white"
                  : "bg-gray-500"
              }`}
            >
              <strong>B</strong>
            </button>
            <button
              type="button"
              onMouseDown={(e) => {
                e.preventDefault();
                handleInlineStyle("ITALIC");
              }}
              className={`px-3 py-1 border rounded ${
                contentState.getCurrentInlineStyle().has("ITALIC")
                  ? "bg-blue-500 text-white"
                  : "bg-gray-500"
              }`}
            >
              <em>I</em>
            </button>
            <button
              type="button"
              onMouseDown={(e) => {
                e.preventDefault();
                handleInlineStyle("UNDERLINE");
              }}
              className={`px-3 py-1 border rounded ${
                contentState.getCurrentInlineStyle().has("UNDERLINE")
                  ? "bg-blue-500 text-white"
                  : "bg-gray-500"
              }`}
            >
              <u>U</u>
            </button>
          </div>

          {/* Editor */}
          <div
            className="border-gray-400 border rounded p-2 cursor-text min-h-48 pointer-events-auto select-text"
            onMouseDown={(e) => {
              if (e.target === e.currentTarget) {
                e.preventDefault();
                editorRef.current?.focus();
              }
            }}
          >
            <Editor
              ref={editorRef}
              editorState={contentState}
              onChange={handleContentChange}
              placeholder="Write your content here..."
            />
          </div>
        </div>
      </div>
      {missing.includes("content") && (
        <p className="text-red-500">Content is required</p>
      )}
      <label className="md:grid md:grid-cols-6 flex flex-col w-full gap-2">
        Author:
        <input
          type="text"
          name="author"
          className="border-gray-400 md:col-start-2 md:col-span-5 border rounded h-8 py-1 px-2 w-full"
          value={postState.author}
          onChange={handleChange}
          required
        />
      </label>
      {missing.includes("author") && (
        <p className="text-red-500">Author is required</p>
      )}
      <label className="md:grid md:grid-cols-6 flex flex-col w-full gap-2">
        Date Posted:
        <input
          type="date"
          name="datePosted"
          value={postState.datePosted}
          onChange={handleChange}
          required
        />
      </label>
      <button
        type="button"
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer"
        onClick={handleSubmit}
      >
        {post ? "Save Post" : "Create Post"}
      </button>
    </form>
  );
}

export function NewPostLayout() {
  const searchParams = useSearchParams()[0];
  const postId = parseInt(searchParams.get("postId") ?? "-1");
  const post =
    postId < 0 || postId >= posts.length
      ? null
      : posts.find((p) => p.id === postId)!;

  return (
    <div className="flex flex-col gap-4 items-center justify-center dark:bg-slate-700 p-10 h-screen">
      <h1 className="text-2xl font-bold">New Post</h1>
      <BlogPostForm
        post={post}
        onSubmit={(post) => {
          if (post.id < posts.length) {
            posts[post.id] = post;
          } else {
            posts.push(post);
          }
        }}
      />
    </div>
  );
}
