"use client";

import { useGetCategoryTreeQuery } from "@/api/category.api";
import { useCreateQuestionMutation } from "@/api/seaqa.api";
import { parseApiError } from "@/api/utils/error-handler";
import { AnimatePresence, motion } from "framer-motion";
import { useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { useForm } from "react-hook-form";
import { toast } from "react-hot-toast";
import Select, { GroupBase, StylesConfig } from "react-select";

interface OptionType {
  value: number;
  label: string;
}

interface FormValues {
  title: string;
  description: string;
}

interface AskQuestionModalProps {
  open: boolean;
  onClose: () => void;
}

// react-select styling tuned to match the modal's light inputs
// (border-gray-200 / rounded-xl / blue-400 focus ring).
const selectStyles: StylesConfig<OptionType, true, GroupBase<OptionType>> = {
  control: (base, state) => ({
    ...base,
    minHeight: "42px",
    borderRadius: "12px",
    borderWidth: "1px",
    borderColor: state.isFocused ? "#60a5fa" : "#e5e7eb",
    boxShadow: state.isFocused ? "0 0 0 2px rgba(96,165,250,0.4)" : "none",
    "&:hover": { borderColor: state.isFocused ? "#60a5fa" : "#d1d5db" },
    backgroundColor: "#fff",
    cursor: "pointer",
    fontSize: "14px",
  }),
  groupHeading: (base) => ({
    ...base,
    fontSize: "13px",
    fontWeight: 700,
    textTransform: "none",
    color: "#111827",
    backgroundColor: "#f9fafb",
    padding: "8px 12px",
    marginBottom: 0,
  }),
  option: (base, state) => ({
    ...base,
    fontSize: "14px",
    fontWeight: 500,
    padding: "9px 14px 9px 24px",
    color: state.isSelected ? "#2563eb" : "#374151",
    backgroundColor: state.isSelected
      ? "rgba(59,130,246,0.08)"
      : state.isFocused
        ? "#eff6ff"
        : "#fff",
    cursor: "pointer",
    "&:active": { backgroundColor: "#eff6ff" },
  }),
  multiValue: (base) => ({
    ...base,
    backgroundColor: "#eff6ff",
    borderRadius: "9999px",
    border: "1px solid rgba(59,130,246,0.3)",
  }),
  multiValueLabel: (base) => ({
    ...base,
    color: "#2563eb",
    fontSize: "12px",
    fontWeight: 600,
    padding: "2px 6px",
  }),
  multiValueRemove: (base) => ({
    ...base,
    color: "#2563eb",
    borderRadius: "0 9999px 9999px 0",
    "&:hover": { backgroundColor: "#3b82f6", color: "#fff" },
  }),
  placeholder: (base) => ({
    ...base,
    color: "#d1d5db",
    fontSize: "14px",
    fontWeight: 400,
  }),
  menu: (base) => ({
    ...base,
    borderRadius: "12px",
    boxShadow: "0 8px 30px rgba(0,0,0,0.10)",
    border: "1px solid #e5e7eb",
    overflow: "hidden",
  }),
  menuPortal: (base) => ({ ...base, zIndex: 200 }),
  menuList: (base) => ({ ...base, padding: "4px 0", maxHeight: "240px" }),
};

export default function AskQuestionModal({
  open,
  onClose,
}: AskQuestionModalProps) {
  const router = useRouter();
  const [selectedCategories, setSelectedCategories] = useState<OptionType[]>(
    [],
  );
  const [categoryError, setCategoryError] = useState("");
  const [done, setDone] = useState(false);

  const { data: categories = [] } = useGetCategoryTreeQuery("seaqa", {
    skip: !open,
  });
  const [createQuestion, { isLoading }] = useCreateQuestionMutation();

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<FormValues>();

  // Lock body scroll + close on Escape while open.
  useEffect(() => {
    if (!open) return;
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    const originalOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.body.style.overflow = originalOverflow;
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [open, onClose]);

  // Reset everything whenever the modal is freshly opened.
  useEffect(() => {
    if (open) {
      reset({ title: "", description: "" });
      setSelectedCategories([]);
      setCategoryError("");
      setDone(false);
    }
  }, [open, reset]);

  const groupedOptions = categories
    .filter((parent) => parent.childCategories.length > 0)
    .map((parent) => ({
      label: parent.name,
      options: parent.childCategories.map((child) => ({
        value: child.id,
        label: child.name,
      })),
    }));

  const onSubmit = async (data: FormValues) => {
    if (selectedCategories.length === 0) {
      setCategoryError("Please select at least one topic.");
      return;
    }
    setCategoryError("");

    try {
      await createQuestion({
        title: data.title,
        description: data.description,
        categoryIds: selectedCategories.map((c) => c.value),
      }).unwrap();
      setDone(true);
    } catch (error: unknown) {
      toast.error(parseApiError(error));
    }
  };

  if (typeof document === "undefined") return null;

  return createPortal(
    <AnimatePresence>
      {open && (
        <motion.div
          role="dialog"
          aria-modal="true"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.2 }}
          className="fixed inset-0 z-[100] flex items-center justify-center"
        >
          {/* Backdrop */}
          <div
            className="absolute inset-0 bg-black/40 backdrop-blur-[2px]"
            onClick={onClose}
          />

          {done ? (
            // ── Success state ──────────────────────────────────────────────
            <motion.div
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.95 }}
              transition={{ duration: 0.2 }}
              className="relative bg-white rounded-2xl shadow-2xl w-full max-w-md mx-4"
            >
              <div className="flex flex-col items-center gap-4 px-8 py-10 text-center">
                <div className="h-14 w-14 rounded-full bg-green-100 flex items-center justify-center">
                  <svg
                    className="h-7 w-7 text-green-500"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                    strokeWidth={2.5}
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      d="M5 13l4 4L19 7"
                    />
                  </svg>
                </div>
                <div className="space-y-2">
                  <h2 className="text-lg font-bold text-[#111827]">
                    Question Submitted!
                  </h2>
                  <p className="text-sm text-[#6b7280] leading-relaxed max-w-xs">
                    Your question will show after it has been reviewed and
                    approved by Admin.
                  </p>
                </div>
                <button
                  type="button"
                  onClick={() => {
                    onClose();
                    // router.push("/questions");
                  }}
                  className="mt-2 px-6 py-2 rounded-full bg-blue-500 hover:bg-blue-600 text-white text-sm font-semibold transition-colors shadow-sm"
                >
                  Okay
                </button>
              </div>
            </motion.div>
          ) : (
            // ── Form state ─────────────────────────────────────────────────
            <motion.div
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.95 }}
              transition={{ duration: 0.2 }}
              className="relative bg-white rounded-2xl shadow-2xl w-full max-w-lg mx-4 flex flex-col max-h-[90vh]"
            >
              <form
                onSubmit={handleSubmit(onSubmit)}
                className="flex flex-col max-h-[90vh]"
              >
                {/* Header */}
                <div className="shrink-0 flex items-center justify-between px-6 py-4 border-b border-[#f3f4f6]">
                  <h2 className="text-base font-bold text-[#111827]">
                    Ask a Question
                  </h2>
                  <button
                    type="button"
                    onClick={onClose}
                    className="h-7 w-7 flex items-center justify-center rounded-full hover:bg-[#f3f4f6] text-[#9ca3af] hover:text-[#4b5563] transition-colors"
                  >
                    <svg
                      className="h-4 w-4"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                      strokeWidth={2}
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        d="M6 18L18 6M6 6l12 12"
                      />
                    </svg>
                  </button>
                </div>

                {/* Body */}
                <div className="overflow-y-auto px-6 py-5 space-y-5">
                  {/* Main Question */}
                  <div className="space-y-1.5">
                    <label className="block text-sm font-semibold text-[#1f2937]">
                      Main Question
                    </label>
                    <p className="text-xs text-[#9ca3af]">
                      Describe your question in as few words as possible
                    </p>
                    <input
                      type="text"
                      placeholder="e.g. What does Rule 8 of COLREGS require?"
                      {...(() => {
                        const field = register("title", {
                          required: "Title is required",
                          minLength: {
                            value: 10,
                            message:
                              "Title must be at least 10 characters long",
                          },
                        });
                        return {
                          ...field,
                          // Always capitalize the first letter regardless of
                          // what the user types, then hand off to RHF.
                          onChange: (
                            e: React.ChangeEvent<HTMLInputElement>,
                          ) => {
                            const value = e.target.value;
                            e.target.value =
                              value.charAt(0).toUpperCase() + value.slice(1);
                            return field.onChange(e);
                          },
                        };
                      })()}
                      className={`w-full text-sm border rounded-xl px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent placeholder:text-[#d1d5db] transition ${
                        errors.title ? "border-red-400" : "border-[#e5e7eb]"
                      }`}
                    />
                    {errors.title && (
                      <p className="text-red-500 text-xs">
                        {errors.title.message}
                      </p>
                    )}
                  </div>

                  {/* Choose Topic */}
                  <div className="space-y-1.5">
                    <label className="block text-sm font-semibold text-[#1f2937]">
                      Choose Topic
                    </label>
                    <p className="text-xs text-[#9ca3af]">
                      Choose the topic that best fits your question
                    </p>
                    <Select<OptionType, true, GroupBase<OptionType>>
                      isMulti
                      options={groupedOptions}
                      value={selectedCategories}
                      onChange={(val) => {
                        setSelectedCategories(val as OptionType[]);
                        if (val.length > 0) setCategoryError("");
                      }}
                      styles={{
                        ...selectStyles,
                        control: (base, state) => ({
                          ...selectStyles.control!(base, state),
                          borderColor: categoryError
                            ? "#f87171"
                            : state.isFocused
                              ? "#60a5fa"
                              : "#e5e7eb",
                        }),
                      }}
                      placeholder="Select a topic…"
                      closeMenuOnSelect={false}
                      hideSelectedOptions={false}
                      menuPortalTarget={document.body}
                      instanceId="ask-topics-select"
                    />
                    {categoryError && (
                      <p className="text-red-500 text-xs">{categoryError}</p>
                    )}
                  </div>

                  {/* Question Description */}
                  <div className="space-y-1.5">
                    <label className="block text-sm font-semibold text-[#1f2937]">
                      Question Description
                    </label>
                    <p className="text-xs text-[#9ca3af]">
                      Use this space to elaborate your question or give context
                      to it
                    </p>
                    <textarea
                      rows={4}
                      placeholder="Provide any additional context or details…"
                      {...(() => {
                        const field = register("description", {
                          required: "Description is required",
                          minLength: {
                            value: 10,
                            message:
                              "Description must be at least 10 characters long",
                          },
                        });
                        return {
                          ...field,
                          // Always capitalize the first letter regardless of
                          // what the user types, then hand off to RHF.
                          onChange: (
                            e: React.ChangeEvent<HTMLTextAreaElement>,
                          ) => {
                            const value = e.target.value;
                            e.target.value =
                              value.charAt(0).toUpperCase() + value.slice(1);
                            return field.onChange(e);
                          },
                        };
                      })()}
                      className={`w-full text-sm border rounded-xl px-3.5 py-2.5 resize-none focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent placeholder:text-[#d1d5db] transition ${
                        errors.description
                          ? "border-red-400"
                          : "border-[#e5e7eb]"
                      }`}
                    />
                    {errors.description && (
                      <p className="text-red-500 text-xs">
                        {errors.description.message}
                      </p>
                    )}
                  </div>
                </div>

                {/* Footer */}
                <div className="shrink-0 flex items-center justify-end gap-2.5 px-6 py-4 border-t border-[#f3f4f6]">
                  <button
                    type="button"
                    onClick={onClose}
                    className="px-4 py-2 text-sm font-medium rounded-xl border border-[#e5e7eb] text-[#4b5563] hover:bg-[#f3f4f6] transition-colors"
                  >
                    Cancel
                  </button>
                  <button
                    type="submit"
                    disabled={isLoading}
                    className="px-5 py-2 text-sm font-semibold rounded-xl bg-blue-500 hover:bg-blue-600 text-white transition-colors disabled:opacity-40 disabled:cursor-not-allowed shadow-sm"
                  >
                    {isLoading ? "Submitting..." : "Submit Question"}
                  </button>
                </div>
              </form>
            </motion.div>
          )}
        </motion.div>
      )}
    </AnimatePresence>,
    document.body,
  );
}
