import { useEffect, useState } from "react";
import { Button, Form, Input, Card, Col, Row, Tag, Spin } from "antd";
import {
  useForm,
  Controller,
  useFieldArray,
  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 { getAxiosErrorMessage } from "@/utils/index.utils";
import { OldQuestionFormValues } from "@/types";
import { useLocation, useNavigate } from "react-router-dom";
import ROUTE_CONSTANTS from "@/constants/route.constants";
import ImageUploader from "@/components/shared/ImageUploader";

const schema = yup
  .object({
    questionText: yup.string().test(
      "question-text-or-image",
      "Question text or image is required",
      function (value) {
        return !!(value || this.parent.questionImage);
      }
    ),
    questionImage: yup.mixed().optional(),
    options: yup
      .array()
      .of(
        yup
          .object({
            option: yup.string().optional(),
            optionImage: yup.mixed().optional(),
          })
          .test(
            "option-or-image",
            "Option text or image is required",
            (value) => !!(value?.option || value?.optionImage),
          ),
      )
      .min(4, "At least four options required")
      .required(),
    correctAnswer: yup.number().required("Correct answer required"),
    explanation: yup.string().optional(),
    explanationImage: yup.mixed().optional(),
  });

const initialFormValues: OldQuestionFormValues = {
  questionText: "",
  questionImage: "",
  options: [
    { option: "", optionImage: "" },
    { option: "", optionImage: "" },
    { option: "", optionImage: "" },
    { option: "", optionImage: "" },
  ],
  correctAnswer: 0,
  explanation: "",
  explanationImage: "",
};

export default function OldQuestionAddPage() {
  const { state, pathname } = useLocation();
  const isEdit = pathname === ROUTE_CONSTANTS.OldQuestionsBankEdit;
  const navigate = useNavigate();
  const [examsList, setExamsList] = useState<
    { id: string; examName: string }[]
  >([]);
  const [isFetchLoading, setIsFetchLoading] = useState(false);
  const [fetchedQuestion, setFetchedQuestion] = useState<any>(null);

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

  const {
    control,
    handleSubmit,
    reset,
    watch,
    setValue,
    getValues,
    formState: { errors, isSubmitting },
  } = useForm<OldQuestionFormValues>({
    resolver,
    defaultValues: initialFormValues,
  });

  const fetchExams = async () => {
    try {
      const res = await API_Instance.get(API_Constants.exams);
      setExamsList(res.data.data);
    } catch (err) {
      toast.error("Failed to fetch exams");
    }
  };

  useEffect(() => {
    fetchExams();
  }, []);

  // Load edit values
  useEffect(() => {
    const initEdit = (data: any) => {
      reset({
        questionText: data.questionText || "",
        questionImage: data.questionImage || "",
        options:
          data.options?.map((o: any) => ({
            option: o.option || "",
            optionImage: o.optionImage || "",
          })) || initialFormValues.options,
        correctAnswer: data.correctAnswer ?? 0,
        explanation: data.explanation || "",
        explanationImage: data.explanationImage || "",
      });
    };

    if (isEdit && state) {
      if (state.options) {
        initEdit(state);
      } else if (state.id) {
        setIsFetchLoading(true);
        API_Instance.get(`${API_Constants.oldQuestions}/${state.id}`)
          .then((res) => {
            initEdit(res.data.data);
            setFetchedQuestion(res.data.data);
          })
          .catch((err) => {
            toast.error(getAxiosErrorMessage(err));
          })
          .finally(() => {
            setIsFetchLoading(false);
          });
      }
    } else {
      reset({
        ...initialFormValues,
      });
    }
  }, [state, pathname, reset, isEdit]);

  const { fields } = useFieldArray({
    control,
    name: "options",
  });

  const onSubmit: SubmitHandler<OldQuestionFormValues> = async (data) => {
    const formData = new FormData();
    formData.append("oldQuestionId", state?.id || "");
    formData.append("questionText", data.questionText || "");
    formData.append("correctAnswer", String(data.correctAnswer));
    if (data.explanation) {
      formData.append("explanation", data.explanation);
    }
    if (data.explanationImage && typeof data.explanationImage !== "string") {
      formData.append("explanationImage", data.explanationImage);
    } else if (data.explanationImage === "") {
      formData.append("explanationImage", "");
    }

    if (data.questionImage && typeof data.questionImage !== "string") {
      formData.append("questionImage", data.questionImage);
    } else if (data.questionImage === "") {
      formData.append("questionImage", "");
    }

    const existingOptionImages: Record<number, string> = {};

    data.options.forEach((o, index) => {
      formData.append("options", o.option || "");

      if (o.optionImage) {
        if (typeof o.optionImage === "string") {
          const uploadedOld = o.optionImage.split("/");
          existingOptionImages[index] = `/${uploadedOld[uploadedOld.length - 2]
            }/${uploadedOld[uploadedOld.length - 1]}`;
        } else {
          formData.append("optionImage", o.optionImage);
          formData.append("optionImageIndexes", String(index));
        }
      }
    });

    formData.append(
      "existingOptionImages",
      JSON.stringify(existingOptionImages),
    );

    try {
      if (state?.id && isEdit) {
        const res = await API_Instance.put(
          `${API_Constants.oldQuestions}/${state.id}`,
          formData,
        );
        toast.success(res.data.message);
        if (state?.supportTicketId) {
          try {
            await API_Instance.patch(`${API_Constants.support}/status/${state.supportTicketId}`, {
              status: "resolved",
            });
            toast.success("Support ticket auto-resolved");
          } catch (ticketErr) {
            console.error("Failed to auto-resolve support ticket", ticketErr);
          }
          navigate("/support");
          return;
        }
        navigate(-1);
      } else {
        const res = await API_Instance.post(
          `${API_Constants.oldQuestions}`,
          formData,
        );
        reset({ ...initialFormValues, questionImage: "", explanationImage: "" });
        toast.success(res.data.message);
      }
    } catch (err) {
      toast.error(getAxiosErrorMessage(err));
    }
  };

  if (isFetchLoading) {
    return (
      <div className="h-64 flex items-center justify-center">
        <Spin size="large" tip="Loading question details..." />
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-3 px-4 pb-6">
      <h2 className="text-xl font-bold text-[#1677ff] mt-2 mb-2">
        {state && isEdit
          ? "Edit Previous Year Question"
          : "Add New Previous Year Question"}
      </h2>

      <Card className="rounded-xl shadow-lg border border-slate-200">
        <Form layout="vertical" onFinish={handleSubmit(onSubmit)}>
          <Row gutter={[20, 4]}>
            {/* QUESTION */}
            <Col span={24}>
              <Form.Item
                label="Question"
                help={errors.questionText?.message}
                validateStatus={errors.questionText ? "error" : ""}
                required
              >
                <Controller
                  name="questionText"
                  control={control}
                  render={({ field }) => (
                    <Input.TextArea
                      {...field}
                      rows={2}
                      placeholder="Type question here..."
                    />
                  )}
                />
              </Form.Item>
            </Col>

            <Col span={24}>
              <Form.Item
                label="Question Image"
                name="questionImage"
                help={errors.questionImage?.message}
                validateStatus={errors.questionImage ? "error" : ""}
              >
                <Controller
                  name="questionImage"
                  control={control}
                  render={({ field }) => (
                    <ImageUploader
                      value={field.value}
                      onChange={(file) => field.onChange(file || "")}
                      onRemove={() => field.onChange("")}
                    />
                  )}
                />
              </Form.Item>
            </Col>

            {/* OPTIONS */}
            <Col span={24}>
              <Form.Item
                label={
                  <span className="font-medium text-slate-700">Options</span>
                }
                required
              >
                {fields.map((op, index) => {
                  const errorMsg = errors.options?.[index]?.message;

                  return (
                    <Form.Item
                      key={op.id}
                      className={`border border-gray-100 p-2 rounded-lg ${errorMsg
                        ? "border-red-500"
                        : index === watch("correctAnswer")
                          ? "bg-[#dcdcdc20] border-gray-200"
                          : ""
                        }`}
                    >
                      <div className="flex items-center gap-3 w-full justify-between">
                        {/* Index Tag */}
                        <div className="w-[75%] flex flex-col gap-2">
                          <div className="flex items-center gap-2">
                            <Tag
                              className={`rounded-2xl text-gray-500 border-none h-8 w-8 flex items-center justify-center font-semibold ${index === watch("correctAnswer")
                                ? "bg-[#16a34a] text-white"
                                : ""
                                }`}
                            >
                              {index + 1}
                            </Tag>

                            {/* Input */}
                            <div className="flex-1">
                              <Controller
                                name={`options.${index}.option`}
                                control={control}
                                render={({ field }) => (
                                  <Input.TextArea
                                    {...field}
                                    className={`w-full ${!errorMsg &&
                                      index === watch("correctAnswer")
                                      ? "border-green-500 hover:border-green-500"
                                      : ""
                                      }`}
                                    placeholder={`Option ${index + 1}`}
                                    rows={2}
                                  />
                                )}
                              />
                            </div>
                          </div>
                          {errorMsg && (
                            <small className="text-md text-red-500">
                              {errorMsg}
                            </small>
                          )}
                        </div>
                        <div className="flex items-center gap-5">
                          <Controller
                            name={`options.${index}.optionImage`}
                            control={control}
                            render={({ field }) => (
                              <ImageUploader
                                value={field.value}
                                onChange={(file) => field.onChange(file || "")}
                                onRemove={() => field.onChange("")}
                              />
                            )}
                          />
                          {/* Correct Answer Radio */}
                          <Controller
                            name="correctAnswer"
                            control={control}
                            render={({ field }) => (
                              <input
                                type="radio"
                                checked={field.value === index}
                                onChange={() => field.onChange(index)}
                                className="h-5 w-5 accent-[#16a34a] cursor-pointer"
                              />
                            )}
                          />
                        </div>
                      </div>
                    </Form.Item>
                  );
                })}
              </Form.Item>
            </Col>

            {/* EXPLANATION */}
            <Col span={24}>
              <Form.Item label="Explanation">
                <Controller
                  name="explanation"
                  control={control}
                  render={({ field }) => <Input.TextArea {...field} rows={2} />}
                />
              </Form.Item>
            </Col>
            <Col span={24}>
              <Form.Item
                label="Explanation Image"
                name="explanationImage"
                help={errors.explanationImage?.message}
                validateStatus={errors.explanationImage ? "error" : ""}
              >
                <Controller
                  name="explanationImage"
                  control={control}
                  render={({ field }) => (
                    <ImageUploader
                      value={field.value}
                      onChange={(file) => field.onChange(file || "")}
                      onRemove={() => field.onChange("")}
                    />
                  )}
                />
              </Form.Item>
            </Col>
          </Row>

          {/* ACTION BUTTONS */}
          <div className="flex justify-end gap-3 mt-5">
            <Button
              onClick={() => navigate(-1)}
            >
              Cancel
            </Button>
            <Button type="primary" htmlType="submit" loading={isSubmitting}>
              {isEdit ? "Update Question" : "Create Question"}
            </Button>
          </div>
        </Form>
      </Card>
    </div>
  );
}
