import toast from "react-hot-toast";
import React, { useEffect, useState } from "react";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import { Button, Form, Input, Spin, Upload, Select } from "antd";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import { FileText, Link as LinkIcon, UploadCloud, CheckCircle } from "lucide-react";

type TabType = "pdf" | "link";

export interface NotesAndLinksUploadProps {
  subjectId: string;
  onSuccess?: () => void;
  onCancel?: () => void;
  initialData?: any;
  defaultTab?: "pdf" | "link";
  subjectTopics?: string[];
}

const NotesAndLinksUpload: React.FC<NotesAndLinksUploadProps> = ({
  subjectId,
  onSuccess,
  onCancel,
  initialData,
  defaultTab,
  subjectTopics = [],
}) => {
  const isEdit = !!initialData?.id;

  const [activeTab, setActiveTab] = useState<TabType>(
    defaultTab ?? (isEdit ? (initialData.type === "LINK" ? "link" : "pdf") : "pdf")
  );
  const [loading, setLoading] = useState(false);
  const [fileList, setFileList] = useState<any[]>([]);

  const [pdfForm] = Form.useForm();
  const [linkForm] = Form.useForm();

  const getDisplayFileName = (value?: string) => {
    if (!value) return "Document.pdf";
    const fileName = value.split(/[\\/]/).pop();
    return fileName ? decodeURIComponent(fileName) : "Document.pdf";
  };

  useEffect(() => {
    if (initialData) {
      const nextTab = initialData.type === "LINK" ? "link" : "pdf";
      setActiveTab(nextTab);

      if (initialData.type === "PDF") {
        if (initialData.files && Array.isArray(initialData.files) && initialData.files.length > 0) {
          const mappedFiles = initialData.files.map((f: any, idx: number) => ({
            uid: `existing-${Date.now()}-${idx}`,
            name: f.name || getDisplayFileName(f.url),
            status: "done",
            url: f.url,
          }));
          setFileList(mappedFiles);
        } else if (initialData.fileUrl || initialData.filePath) {
          const existingFileName =
            initialData.fileName ||
            initialData.originalName ||
            getDisplayFileName(initialData.fileUrl || initialData.filePath);

          setFileList([
            {
              uid: initialData.id || `existing-${Date.now()}`,
              name: existingFileName,
              status: "done",
              url: initialData.fileUrl || initialData.filePath,
            },
          ]);
        } else {
          setFileList([]);
        }

        pdfForm.setFieldsValue({
          title: initialData.title,
          topics: initialData.topics || [],
        });
      } else {
        setFileList([]);
        linkForm.setFieldsValue({
          title: initialData.title,
          linkUrl: initialData.linkUrl,
          topics: initialData.topics || [],
        });
      }
    } else {
      setFileList([]);
      if (defaultTab) {
        setActiveTab(defaultTab);
      }
    }
  }, [initialData, defaultTab, pdfForm, linkForm]);

  const handlePdfSubmit = async (values: any) => {
    if (!isEdit && fileList.length === 0) {
      toast.error("Please select a PDF file.");
      return;
    }
    
    for (const f of fileList) {
      if (f.originFileObj && f.originFileObj.size > 3 * 1024 * 1024) {
        toast.error(`File ${f.name} must be smaller than 3MB`);
        return;
      }
    }

    setLoading(true);
    try {
      if (isEdit) {
        const formData = new FormData();
        formData.append("title", values.title);
        formData.append("type", "PDF");
        formData.append("subjectId", subjectId);
        formData.append("topics", JSON.stringify(values.topics || []));

        const existingFiles = fileList
          .filter((f) => f.url)
          .map((f) => ({ name: f.name, url: f.url }));
        formData.append("existingFiles", JSON.stringify(existingFiles));

        const newFiles = fileList.filter((f) => f.originFileObj);
        newFiles.forEach((f) => {
          if (f.originFileObj) formData.append("files", f.originFileObj);
        });

        await API_Instance.put(`${API_Constants.notesLinks}/${initialData.id}`, formData, {
          headers: { "Content-Type": "multipart/form-data" },
        });

        toast.success("PDF updated successfully!");
      } else {
        const formData = new FormData();
        formData.append("title", values.title);
        formData.append("type", "PDF");
        formData.append("subjectId", subjectId);
        formData.append("topics", JSON.stringify(values.topics || []));

        fileList.forEach((f) => {
          if (f.originFileObj) formData.append("files", f.originFileObj);
        });

        await API_Instance.post(API_Constants.notesLinks, formData, {
          headers: { "Content-Type": "multipart/form-data" },
        });

        toast.success(fileList.length > 1 ? "PDFs uploaded successfully!" : "PDF uploaded successfully!");
      }
      pdfForm.resetFields();
      setFileList([]);
      if (onSuccess) onSuccess();
    } catch (err) {
      toast.error(getAxiosErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  const handleLinkSubmit = async (values: any) => {
    setLoading(true);
    try {
      if (isEdit) {
        await API_Instance.put(`${API_Constants.notesLinks}/${initialData.id}`, {
          title: values.title,
          linkUrl: values.linkUrl,
          topics: values.topics || [],
        });
        toast.success("Link updated successfully!");
      } else {
        await API_Instance.post(API_Constants.notesLinks, {
          type: "LINK",
          subjectId,
          topics: values.topics || [],
          links: values.links,
        });
        toast.success(values.links.length > 1 ? "Links submitted successfully!" : "Link submitted successfully!");
      }
      linkForm.resetFields();
      if (onSuccess) onSuccess();
    } catch (err) {
      toast.error(getAxiosErrorMessage(err));
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="w-full">
      <div className="bg-white rounded-xl">
        <Spin spinning={loading}>
          {activeTab === "pdf" ? (
            <Form
              form={pdfForm}
              layout="vertical"
              onFinish={handlePdfSubmit}
              className="space-y-4"
            >
              <Form.Item
                name="title"
                label={<span className="font-medium text-slate-700">Notes Title</span>}
                rules={[{ required: true, message: "Please enter a title" }]}
              >
                <Input
                  placeholder="Title"
                  className="rounded-lg"
                  size="large"
                />
              </Form.Item>

              <Form.Item
                name="topics"
                label={<span className="font-medium text-slate-700">Topics (Optional)</span>}
              >
                <Select
                  mode="multiple"
                  placeholder="Select topics"
                  className="rounded-lg"
                  size="large"
                  options={subjectTopics.map((t) => ({ label: t, value: t }))}
                  allowClear
                />
              </Form.Item>

              <Form.Item
                label={<span className="font-medium text-slate-700">{isEdit ? "Replace PDF File" : "PDF File"}</span>}
                required={!isEdit}
              >
                <Upload.Dragger
                  accept=".pdf"
                  multiple={!isEdit}
                  maxCount={isEdit ? 1 : undefined}
                  fileList={fileList}
                  beforeUpload={() => false}
                  onChange={({ fileList: fl }) => setFileList(fl)}
                  className="rounded-xl"
                >
                  <div className="py-4">
                    <div className="w-12 h-12 bg-blue-50 rounded-xl flex items-center justify-center mx-auto mb-3">
                      <FileText size={24} className="text-blue-500" />
                    </div>
                    <p className="text-slate-700 font-medium">
                      Click or drag PDF to upload
                    </p>
                    <p className="text-slate-400 text-xs mt-1">
                      PDF only · Max size per file: 3MB
                    </p>
                  </div>
                </Upload.Dragger>
              </Form.Item>

              <div className="flex gap-3 mt-6 justify-end">
                {onCancel && (
                  <Button onClick={onCancel} className="h-10 rounded-lg">
                    Cancel
                  </Button>
                )}
                <Button
                  type="primary"
                  htmlType="submit"
                  loading={loading}
                  className="h-10 rounded-lg bg-blue-600 hover:bg-blue-700"
                  icon={isEdit ? <CheckCircle size={16} /> : <UploadCloud size={16} />}
                >
                  {isEdit ? "Save Changes" : "Upload PDF"}
                </Button>
              </div>
            </Form>
          ) : (
            <Form
              form={linkForm}
              layout="vertical"
              onFinish={handleLinkSubmit}
              className="space-y-4"
              initialValues={{ links: [{ title: "", linkUrl: "" }] }}
            >
              <Form.Item
                name="topics"
                label={<span className="font-medium text-slate-700">Topics (Optional)</span>}
              >
                <Select
                  mode="multiple"
                  placeholder="Select topics"
                  className="rounded-lg"
                  size="large"
                  options={subjectTopics.map((t) => ({ label: t, value: t }))}
                  allowClear
                />
              </Form.Item>

              {isEdit ? (
                <>
                  <Form.Item
                    name="title"
                    label={<span className="font-medium text-slate-700">Link Title</span>}
                    rules={[{ required: true, message: "Please enter a title" }]}
                  >
                    <Input placeholder="Title" className="rounded-lg" size="large" />
                  </Form.Item>
                  <Form.Item
                    name="linkUrl"
                    label={<span className="font-medium text-slate-700">URL</span>}
                    rules={[
                      { required: true, message: "Please enter a URL" },
                      { type: "url", message: "Please enter a valid URL" },
                    ]}
                  >
                    <Input
                      placeholder="https://youtube.com/watch?v=..."
                      prefix={<LinkIcon size={14} className="text-slate-400" />}
                      className="rounded-lg"
                      size="large"
                    />
                  </Form.Item>
                </>
              ) : (
                <Form.List name="links">
                  {(fields, { add, remove }) => (
                    <>
                      <div className="max-h-[40vh] overflow-y-auto pr-2 space-y-4 mb-4 custom-scrollbar">
                        {fields.map(({ key, name, ...restField }, index) => (
                          <div key={key} className="flex gap-4 items-start bg-slate-50 p-4 rounded-xl border border-slate-100">
                            <div className="flex-1 space-y-4">
                              <Form.Item
                                {...restField}
                                name={[name, 'title']}
                                label={<span className="font-medium text-slate-700">Link Title {index + 1}</span>}
                                rules={[{ required: true, message: "Please enter a title" }]}
                                className="mb-0"
                              >
                                <Input placeholder="Title" className="rounded-lg" size="large" />
                              </Form.Item>
                              <Form.Item
                                {...restField}
                                name={[name, 'linkUrl']}
                                label={<span className="font-medium text-slate-700">URL</span>}
                                rules={[
                                  { required: true, message: "Please enter a URL" },
                                  { type: "url", message: "Please enter a valid URL" },
                                ]}
                                className="mb-0"
                              >
                                <Input
                                  placeholder="https://youtube.com/watch?v=..."
                                  prefix={<LinkIcon size={14} className="text-slate-400" />}
                                  className="rounded-lg"
                                  size="large"
                                />
                              </Form.Item>
                            </div>
                            {fields.length > 1 && (
                              <Button
                                type="text"
                                danger
                                onClick={() => remove(name)}
                                className="mt-8"
                              >
                                Remove
                              </Button>
                            )}
                          </div>
                        ))}
                      </div>
                      <Form.Item>
                        <Button type="dashed" onClick={() => add()} block className="h-10 rounded-lg border-blue-200 text-blue-600 bg-blue-50 hover:bg-blue-100 hover:border-blue-300">
                          + Add Another Link
                        </Button>
                      </Form.Item>
                    </>
                  )}
                </Form.List>
              )}

              <div className="flex gap-3 mt-6 justify-end">
                {onCancel && (
                  <Button onClick={onCancel} className="h-10 rounded-lg">
                    Cancel
                  </Button>
                )}
                <Button
                  type="primary"
                  htmlType="submit"
                  loading={loading}
                  className="h-10 rounded-lg bg-indigo-600 hover:bg-indigo-700"
                  icon={isEdit ? <CheckCircle size={16} /> : <LinkIcon size={16} />}
                >
                  {isEdit ? "Save Changes" : "Submit Link"}
                </Button>
              </div>
            </Form>
          )}
        </Spin>
      </div>
    </div>
  );
};

export default NotesAndLinksUpload;