import { useEffect, useState } from "react";
import { Button, Card, Form, Input, Pagination, Popconfirm, Select, Spin } from "antd";
import {
  Plus,
  Edit,
  X,
  LayoutGrid,
  List,
  Trash2,
  Search,
  BookOpen,
  Info,
} from "lucide-react";
import { useDebounce } from "@/hooks/useDebounce";
import {
  useForm,
  Controller,
  type SubmitHandler,
  Resolver,
} from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { API_Instance } from "../../api/axios.instance";
import API_Constants from "../../constants/api.constants";
import toast from "react-hot-toast";
import Modal from "@/components/shared/Modal";
import { useNavigate } from "react-router-dom";
import { IPagination, ISubjectTopics } from "@/types";
import { buildQuery, getAxiosErrorMessage } from "@/utils/index.utils";
import { useAuth } from "@/hooks/useAuth";
import { fetchLanguageOptions } from "@/hooks/useLanguageOptions";

type SubjectCategoryFormValues = Omit<ISubjectTopics, "id">;

const schema = yup.object({
  subjectName: yup.string().required("Subject Name is required"),
  language: yup.string().optional(),
  topics: yup.array().of(yup.string()).required("Topics are required"),
});

const initialPagination: IPagination = {
  page: 1,
  limit: 10,
  total: 0,
  totalPages: 0,
};

export default function Subjects() {
  const navigate = useNavigate();
  const { user } = useAuth();
  const [subjects, setSubjects] = useState<ISubjectTopics[]>([]);
  const [loading, setLoading] = useState(false);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingSubject, setEditingSubject] = useState<ISubjectTopics | null>(
    null,
  );
  const [tagInput, setTagInput] = useState<string>("");
  const [pagination, setPagination] = useState(initialPagination);
  const [viewMode, setViewMode] = useState<"list" | "grid">("list");
  const [search, setSearch] = useState("");
  const debouncedSearch = useDebounce(search, 600);
  const [languageOptions, setLanguageOptions] = useState<any[]>([]);

  useEffect(() => {
    const loadLanguages = async () => {
      try {
        const options = await fetchLanguageOptions();
        setLanguageOptions(options);
      } catch {
        setLanguageOptions([]);
      }
    };
    void loadLanguages();
  }, []);

  const resolver = yupResolver(
    schema,
  ) as unknown as Resolver<SubjectCategoryFormValues>;

  const {
    watch,
    control,
    handleSubmit,
    setValue,
    reset,
    getValues,
    formState: { errors, isSubmitting },
  } = useForm<SubjectCategoryFormValues>({
    resolver,
    defaultValues: { subjectName: "", language: undefined, topics: [] },
  });

  const topics = watch("topics") || [];

  const fetchSubjects = async (
    page: number = pagination.page,
    limit: number = pagination.limit,
    filters: any = {},
  ) => {
    setLoading(true);
    const query = buildQuery(
      { ...filters, search: debouncedSearch },
      page,
      limit,
    );
    try {
      const res = await API_Instance.get(API_Constants.subjects + `?${query}`);
      setSubjects(res.data.data);
      setPagination(res.data.meta);
    } catch (err) {
      toast.error("Failed to fetch subjects");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchSubjects(pagination.page, pagination.limit, {});
  }, [debouncedSearch, pagination.page, pagination.limit]);

  useEffect(() => {
    if (editingSubject) {
      reset({
        subjectName: editingSubject.subjectName,
        language: editingSubject.language || undefined,
        topics: editingSubject.topics || [],
      });
    } else {
      reset({ subjectName: "", language: undefined, topics: [] });
    }
  }, [editingSubject, reset]);

  const openModal = (subject: ISubjectTopics | null = null) => {
    if (subject) {
      setEditingSubject(subject);
    } else {
      setEditingSubject(null);
      reset({ subjectName: "", language: undefined, topics: [] });
    }
    setIsModalOpen(true);
  };

  const closeModal = () => {
    setEditingSubject(null);
    setIsModalOpen(false);
    reset({ subjectName: "", language: undefined, topics: [] });
  };

  const onFormSubmit: SubmitHandler<SubjectCategoryFormValues> = async (
    data,
  ) => {
    try {
      if (editingSubject) {
        await API_Instance.put(
          `${API_Constants.subjects}/${editingSubject.id}`,
          { ...data, language: data.language || null }
        );
        toast.success("Subject updated successfully");
      } else {
        await API_Instance.post(API_Constants.subjects, { ...data, language: data.language || null });
        toast.success("Subject added successfully");
      }
      await fetchSubjects(pagination.page, pagination.limit, {});
      closeModal();
    } catch (err) {
      toast.error(getAxiosErrorMessage(err) || "Failed to save subject");
    }
  };

  const handleDelete = async (subject: ISubjectTopics) => {
    try {
      await API_Instance.delete(`${API_Constants.subjects}/${subject.id}`);
      toast.success("Subject deleted successfully");
      await fetchSubjects(pagination.page, pagination.limit, {});
    } catch (err) {
      toast.error(getAxiosErrorMessage(err) || "Failed to delete subject");
    }
  };

  const handleAddTag = () => {
    if (tagInput.trim() === "") return;

    const currentTopics = getValues("topics") ?? [];
    const normalizedTopics = currentTopics.map((topic: string) =>
      topic.toLowerCase(),
    );
    if (normalizedTopics.includes(tagInput.toLowerCase())) {
      toast.error("Topic Name already exists");
      return;
    }

    setValue("topics", [...currentTopics, tagInput], { shouldDirty: true });
    setTagInput("");
  };

  const handleRemoveTag = (tag: string) => {
    const currentTopics = getValues("topics") ?? [];
    setValue(
      "topics",
      currentTopics.filter((t: string) => t !== tag),
      { shouldDirty: true },
    );
  };

  const instituionRole = user?.role === "INSTITUTION";

  return (
    <div className="flex flex-col gap-4 px-4 py-6">
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
        <div>
          <h2 className="text-2xl font-bold text-slate-800 flex items-center gap-2">
            <BookOpen className="text-blue-600" /> Subject & Topic Management
          </h2>
          <p className="text-slate-500 text-sm mt-1">
            Add/Manage Subjects & Topics.
          </p>
        </div>
        {
          instituionRole && (
            <Button
              type="primary"
              icon={<Plus className="h-4 w-4" />}
              className="!bg-brand-green hover:!bg-brand-green/80 flex items-center gap-2"
              onClick={() => openModal()}
            >
              Add New Subject
            </Button>
          )
        }
      </div>

      <Card className="shadow-sm border border-slate-200 rounded-xl">
        <div className="flex flex-col md:flex-row justify-between items-center gap-4 mb-6">
          <div className="flex gap-4 items-center w-full md:w-auto">
            <Input
              placeholder="Search by Subject Name..."
              prefix={<Search size={16} className="text-slate-400" />}
              className="w-full md:w-72"
              allowClear
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
            <div className="flex items-center bg-slate-50 p-1 rounded-lg border border-slate-200">
              <button
                onClick={() => setViewMode("grid")}
                className={`p-1.5 rounded-md transition-all ${viewMode === "grid"
                  ? "bg-white text-blue-600 shadow-sm"
                  : "text-slate-400 hover:text-slate-600"
                  }`}
                title="Grid view"
              >
                <LayoutGrid size={18} />
              </button>
              <button
                onClick={() => setViewMode("list")}
                className={`p-1.5 rounded-md transition-all ${viewMode === "list"
                  ? "bg-white text-blue-600 shadow-sm"
                  : "text-slate-400 hover:text-slate-600"
                  }`}
                title="List view"
              >
                <List size={18} />
              </button>
            </div>
          </div>
          <div className="text-slate-500 text-sm">
            Total Subjects:{" "}
            <span className="font-semibold text-slate-800">
              {pagination.total}
            </span>
          </div>
        </div>

        {loading ? (
          <div className="h-64 flex items-center justify-center">
            <Spin />
          </div>
        ) : subjects.length === 0 ? (
          <div className="h-64 flex flex-col items-center justify-center text-slate-400 border-2 border-dashed border-slate-100 rounded-xl">
            <BookOpen size={48} className="text-slate-200 mb-2" />
            <p>No subjects found</p>
          </div>
        ) : (
          <div
            className={`grid grid-cols-1 ${viewMode === "grid"
              ? "md:grid-cols-2 lg:grid-cols-3"
              : "md:grid-cols-1"
              } gap-4`}
          >
            {subjects.map((subject) => (
              <div
                key={subject.id}
                className="group bg-white p-5 rounded-xl border border-slate-200 hover:border-blue-200 hover:shadow-md transition-all relative overflow-hidden flex flex-col h-full"
              >
                <div className="flex justify-between items-start gap-4 mb-4">
                  <div className="flex-1">
                    <div className="flex flex-wrap items-center gap-2">
                      <h3 className="text-lg font-bold text-slate-800 group-hover:text-blue-600 transition-colors">
                        {subject.subjectName}
                      </h3>
                      {subject.language && (
                        <span className="px-2 py-0.5 bg-blue-100 text-blue-700 text-[10px] font-bold rounded-full uppercase tracking-wider">
                          {subject.language}
                        </span>
                      )}
                    </div>
                    {/* <p className="text-slate-500 text-xs mt-1">
                      ID: {subject.id.slice(-8).toUpperCase()}
                    </p> */}
                  </div>
                  <div className="flex gap-2">
                    <button
                      onClick={() => openModal(subject)}
                      className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
                      title="Edit"
                    >
                      <Edit size={18} />
                    </button>{
                      instituionRole && (
                        <Popconfirm
                          title="Delete Subject"
                          description="Are you sure you want to delete this subject?"
                          onConfirm={() => handleDelete(subject)}
                          okText="Yes, Delete"
                          cancelText="Cancel"
                          okButtonProps={{ danger: true }}
                        >
                          <button
                            className="p-2 text-slate-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-all"
                            title="Delete"
                          >
                            <Trash2 size={18} />
                          </button>
                        </Popconfirm>
                      )
                    }

                  </div>
                </div>

                <div className="mt-auto">
                  <div className="flex items-center gap-2 mb-2">
                    <span className="text-xs font-semibold text-slate-400 uppercase tracking-wider">
                      Topics
                    </span>
                    <div className="h-px flex-1 bg-slate-100"></div>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    {subject.topics.length > 0
                      ? subject.topics.map((topic, idx) => (
                        <span
                          key={idx}
                          className="px-2 py-1 bg-slate-50 text-slate-600 text-[11px] font-medium rounded border border-slate-100 group-hover:bg-white group-hover:border-blue-100 transition-all"
                        >
                          {topic}
                        </span>
                      ))
                      : null}
                    <button
                      type="button"
                      onClick={() => openModal(subject)}
                      className="px-2 py-1 border border-dashed border-slate-200 text-slate-400 text-[11px] font-medium rounded hover:bg-blue-50 hover:text-blue-600 hover:border-blue-200 transition-all flex items-center gap-1"
                    >
                      <Plus className="w-3 h-3" /> Add Topic
                    </button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}

        <div className="flex justify-end mt-8">
          <Pagination
            current={pagination.page || initialPagination.page}
            total={pagination.total || initialPagination.total}
            pageSize={pagination.limit || initialPagination.limit}
            onChange={(p, pageSize) => {
              setPagination((prev) => ({
                ...prev,
                page: p,
                limit: pageSize,
              }));
            }}
            showSizeChanger
            showTotal={(total) => `Total ${total} items`}
          />
        </div>
      </Card>

      <Modal
        isOpen={isModalOpen}
        onClose={closeModal}
        title={editingSubject ? "Edit Subject" : "Add Subject"}
      >
        <Form layout="vertical" onFinish={handleSubmit(onFormSubmit)}>
          <Form.Item
            label="Subject Name"
            validateStatus={errors.subjectName ? "error" : ""}
            help={errors.subjectName?.message}
          >
            <Controller
              name="subjectName"
              control={control}
              render={({ field }) => (
                <Input {...field} placeholder="Enter subject name" />
              )}
            />
          </Form.Item>
          <div className="mb-4">
            <Form.Item
              label="Language"
              validateStatus={errors.language ? "error" : ""}
              help={errors.language?.message}
              className="!mb-1"
            >
              <Controller
                name="language"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    placeholder="Select language if this is a language paper"
                    options={languageOptions}
                    allowClear
                  />
                )}
              />
            </Form.Item>
            <p className="text-[11px] text-slate-500 flex items-start gap-1.5 leading-tight mt-1">
              <Info size={14} className="text-blue-500 shrink-0 mt-0.5" />
              <span className="mt-0.5">
                Select only for Language Papers (e.g., Tamil). Leave empty for general subjects.
              </span>
            </p>
          </div>

          <div className="flex items-end gap-2">
            <Form.Item label="Topics" className="!m-0 flex-1">
              <div className="flex flex-wrap gap-2 mb-2">
                {topics.length > 0 &&
                  topics.map((topic, idx) => (
                    <span
                      key={idx}
                      className="px-2 py-1 bg-slate-50 text-slate-600 text-[11px] font-medium rounded border border-slate-100 flex items-center gap-2"
                    >
                      {topic}{" "}
                      <X
                        className="h-3 w-3 cursor-pointer hover:text-red-500"
                        onClick={() => handleRemoveTag(topic)}
                      />
                    </span>
                  ))}
              </div>

              <Input
                value={tagInput}
                onChange={(e) => setTagInput(e.target.value)}
                placeholder="Enter topic name"
                onPressEnter={(e) => {
                  e.preventDefault();
                  handleAddTag();
                }}
              />
            </Form.Item>
            <Button
              type="dashed"
              onClick={handleAddTag}
              icon={<Plus size={14} />}
              className="flex items-center"
            >
              Add
            </Button>
          </div>
          <div className="flex justify-end gap-3 mt-6">
            <Button onClick={closeModal}>Cancel</Button>
            <Button type="primary" htmlType="submit" loading={isSubmitting}>
              Save Subject
            </Button>
          </div>
        </Form>
      </Modal>
    </div>
  );
}

