import dayjs from "dayjs";
import toast from "react-hot-toast";
import type { ColumnsType } from "antd/es/table";
import { useDebounce } from "@/hooks/useDebounce";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { CheckCircle, ExternalLink, Link as LinkIcon, Search, XCircle } from "lucide-react";
import { Button, Input, Modal, Pagination, Popconfirm, Select, Table, Tag, Form, Card } from "antd";

interface INoteLink {
    id: string;
    title: string;
    type: "PDF" | "LINK";
    fileUrl: string | null;
    linkUrl: string | null;
    verification: "PENDING" | "VERIFIED" | "REJECTED";
    rejectReason: string | null;
    subjectId: string;
    subject: { id: string; subjectName: string };
    institutionId: string;
    institutionName: string | null;
    createdAt: string;
    updatedAt: string;
    _count?: { reports: number };
}

const VERIFICATION_COLORS: Record<string, string> = {
    PENDING: "orange",
    VERIFIED: "green",
    REJECTED: "red",
};

const NotesLinksApprovalPage: React.FC = () => {
    const [items, setItems] = useState<INoteLink[]>([]);
    const [loading, setLoading] = useState(false);
    const [search, setSearch] = useState("");
    const [verificationFilter, setVerificationFilter] = useState<string>("ALL");
    const [page, setPage] = useState(1);
    const [limit, setLimit] = useState(10);
    const [total, setTotal] = useState(0);
    const debouncedSearch = useDebounce(search, 500);

    const [institutions, setInstitutions] = useState<{ id: string; name: string }[]>([]);
    const [subjects, setSubjects] = useState<{ id: string; subjectName: string; institutionId?: string }[]>([]);
    const [institutionFilter, setInstitutionFilter] = useState<string>("");
    const [subjectFilter, setSubjectFilter] = useState<string>("");

    const [rejectModalOpen, setRejectModalOpen] = useState(false);
    const [rejectingId, setRejectingId] = useState<string | null>(null);
    const [rejectLoading, setRejectLoading] = useState(false);
    const [rejectForm] = Form.useForm();

    const fetchItems = useCallback(async () => {
        setLoading(true);
        try {
            const params: Record<string, any> = {
                page,
                limit,
                type: "LINK",
            };
            if (verificationFilter) params.verification = verificationFilter;
            if (institutionFilter) params.institutionId = institutionFilter;
            if (subjectFilter) params.subjectId = subjectFilter;
            if (debouncedSearch) params.search = debouncedSearch;

            const res = await API_Instance.get(API_Constants.notesLinks, { params });
            setItems(res.data?.data || []);
            setTotal(res.data?.pagination?.total || 0);
        } catch (err) {
            toast.error(getAxiosErrorMessage(err));
        } finally {
            setLoading(false);
        }
    }, [page, limit, verificationFilter, institutionFilter, subjectFilter, debouncedSearch]);

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

    useEffect(() => {
        const fetchInstitutions = async () => {
            try {
                const res = await API_Instance.get(API_Constants.institutionsList, { params: { limit: 100 } });
                setInstitutions(res.data.data || []);
            } catch (err) {
                console.error("Error fetching institutions:", err);
            }
        };

        fetchInstitutions();
    }, []);

    useEffect(() => {
        const fetchSubjects = async () => {
            if (!institutionFilter) {
                setSubjects([]);
                return;
            }

            try {
                const res = await API_Instance.get(API_Constants.subjects, {
                    params: { limit: 100, institutionId: institutionFilter },
                });
                setSubjects(res.data.data || []);
            } catch (err) {
                console.error("Error fetching subjects:", err);
                setSubjects([]);
            }
        };

        fetchSubjects();
    }, [institutionFilter]);

    const filteredSubjectOptions = useMemo(
        () =>
            institutionFilter
                ? subjects.filter((subject) => subject.institutionId === institutionFilter)
                : [],
        [subjects, institutionFilter]
    );

    const handleVerifyLink = async (id: string) => {
        try {
            await API_Instance.patch(`${API_Constants.notesLinks}/${id}/verify`, {
                verification: "VERIFIED",
            });
            toast.success("Link verified successfully.");
            fetchItems();
        } catch (err) {
            toast.error(getAxiosErrorMessage(err));
        }
    };

    const openRejectModal = (id: string) => {
        setRejectingId(id);
        rejectForm.resetFields();
        setRejectModalOpen(true);
    };

    const handleReject = async () => {
        const values = await rejectForm.validateFields();
        setRejectLoading(true);
        try {
            await API_Instance.patch(`${API_Constants.notesLinks}/${rejectingId}/verify`, {
                verification: "REJECTED",
                rejectReason: values.rejectReason,
            });
            toast.success("Link rejected.");
            setRejectModalOpen(false);
            fetchItems();
        } catch (err) {
            toast.error(getAxiosErrorMessage(err));
        } finally {
            setRejectLoading(false);
        }
    };

    const columns: ColumnsType<INoteLink> = [
        {
            title: "Title & Subject",
            dataIndex: "title",
            key: "title",
            className: "!pl-4",
            render: (title: string, record: INoteLink) => (
                <div className="flex flex-col gap-1.5 items-start max-w-[280px]">
                    <span className="text-sm font-medium text-slate-800 truncate w-full block" title={title}>
                        {title}
                    </span>
                    {record.subject?.subjectName && (
                        <span className="px-2 py-0.5 bg-indigo-50 text-indigo-600 border border-indigo-100 rounded text-[10px] font-medium max-w-full truncate" title={record.subject.subjectName}>
                            {record.subject.subjectName}
                        </span>
                    )}
                </div>
            ),
        },
        {
            title: "Institution",
            dataIndex: "institutionName",
            key: "institutionName",
            render: (name: string | null) => (
                <span className="text-sm text-slate-600">{name || "—"}</span>
            ),
        },
        {
            title: "Status",
            dataIndex: "verification",
            key: "verification",
            render: (v: string) => (
                <Tag color={VERIFICATION_COLORS[v] || "default"} className="font-medium capitalize text-xs">
                    {v}
                </Tag>
            ),
        },
        {
            title: "Reject Reason",
            dataIndex: "rejectReason",
            key: "rejectReason",
            render: (reason: string | null) =>
                reason ? (
                    <span className="text-xs text-red-600 max-w-[180px] block">{reason}</span>
                ) : (
                    <span className="text-xs text-slate-400">—</span>
                ),
        },
        {
            title: "Submitted",
            dataIndex: "createdAt",
            key: "createdAt",
            render: (date: string) => (
                <span className="text-xs text-slate-500 italic">
                    {dayjs(date).format("DD-MM-YYYY HH:mm:ss A")}
                </span>
            ),
        },
        {
            title: "Link URL",
            dataIndex: "linkUrl",
            key: "linkUrl",
            render: (url: string | null) =>
                url ? (
                    <div className="max-w-[200px] truncate text-xs">
                        <a
                            href={url}
                            target="_blank"
                            rel="noreferrer"
                            className="text-blue-600 hover:underline"
                            title={url}
                        >
                            {url}
                        </a>
                    </div>
                ) : (
                    <span className="text-xs text-slate-400">—</span>
                ),
        },
        {
            title: "Actions",
            key: "actions",
            render: (_: any, record: INoteLink) => (
                <div className="flex items-center gap-2">
                    {record.verification !== "VERIFIED" && (
                        <Popconfirm
                            title="Verify this link?"
                            description="Are you sure you want to verify this link?"
                            onConfirm={() => handleVerifyLink(record.id)}
                            okText="Verify"
                            cancelText="Cancel"
                        >
                            <Button
                                type="default"
                                size="small"
                                icon={<CheckCircle size={14} />}
                                className="text-emerald-600 border-emerald-300 hover:bg-emerald-50 flex items-center gap-1 text-xs"
                            >
                                Verify
                            </Button>
                        </Popconfirm>
                    )}
                    {record.verification !== "REJECTED" && (
                        <Button
                            type="default"
                            size="small"
                            danger
                            icon={<XCircle size={14} />}
                            className="flex items-center gap-1 text-xs"
                            onClick={() => openRejectModal(record.id)}
                        >
                            Reject
                        </Button>
                    )}
                </div>
            ),
        },
    ];

    return (
        <div className="p-6 space-y-6">
            <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
                <div>
                    <h2 className="text-2xl font-bold text-slate-800 flex items-center gap-2">
                        <LinkIcon className="text-blue-600" size={24} />
                        Link Approval
                    </h2>
                    <p className="text-sm text-slate-500 mt-1">
                        Review and approve or reject links submitted by institutions.
                    </p>
                </div>
            </div>

            <Card className="shadow-sm border border-slate-200 rounded-xl">
                <div className="flex justify-between items-center mb-4">
                    <div className="flex flex-wrap items-center gap-2 mb-4">
                        <Input
                            prefix={<Search size={16} className="text-slate-400" />}
                            placeholder="Search by title..."
                            value={search}
                            onChange={(e) => { setSearch(e.target.value); setPage(1); }}
                            className="w-64 rounded-lg"
                        />
                        <Select
                            value={institutionFilter}
                            onChange={(v) => {
                                setInstitutionFilter(v);
                                setSubjectFilter("");
                                setPage(1);
                            }}
                            className="w-56"
                            showSearch
                            filterOption={(input, option) =>
                                (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
                            }
                            options={[
                                { label: "All Institutions", value: "" },
                                ...institutions.map((inst) => ({
                                    label: inst.name || "Unknown",
                                    value: inst.id,
                                })),
                            ]}
                            placeholder="Filter by institution"
                        />
                        <Select
                            value={subjectFilter}
                            onChange={(v) => { setSubjectFilter(v); setPage(1); }}
                            className="w-48"
                            showSearch
                            disabled={!institutionFilter}
                            filterOption={(input, option) =>
                                (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
                            }
                            options={[
                                { label: "All Subjects", value: "" },
                                ...filteredSubjectOptions.map((subject) => ({
                                    label: subject.subjectName || "Unknown",
                                    value: subject.id,
                                })),
                            ]}
                            placeholder={institutionFilter ? "Filter by subject" : "Select institution first"}
                        />
                        <Select
                            value={verificationFilter}
                            onChange={(v) => { setVerificationFilter(v); setPage(1); }}
                            className="w-44"
                            options={[
                                { label: "All", value: "" },
                                { label: "Pending", value: "PENDING" },
                                { label: "Verified", value: "VERIFIED" },
                                { label: "Rejected", value: "REJECTED" },
                            ]}
                            placeholder="Filter by status"
                        />
                    </div>

                    <span className="ml-auto text-xs text-slate-500">
                        {total} result{total !== 1 ? "s" : ""}
                    </span>
                </div>

                <Table
                    dataSource={items}
                    columns={columns}
                    rowKey="id"
                    loading={loading}
                    pagination={false}
                    scroll={{ x: 900 }}
                    size="middle"
                    locale={{ emptyText: "No links found." }}
                />
                <div className="flex justify-end p-4 border-t border-slate-100">
                    <Pagination
                        current={page}
                        total={total}
                        pageSize={limit}
                        onChange={(p, size) => {
                            setPage(p);
                            setLimit(size);
                        }}
                        onShowSizeChange={(current, size) => {
                            setPage(1);
                            setLimit(size);
                        }}
                        showSizeChanger
                        showTotal={(t) => `Total ${t} items`}
                    />
                </div>
            </Card>

            <Modal
                open={rejectModalOpen}
                onCancel={() => setRejectModalOpen(false)}
                title="Reject Link"
                footer={
                    <div className="flex justify-end gap-2 mt-4">
                        <Button onClick={() => setRejectModalOpen(false)}>Cancel</Button>
                        <Button
                            type="primary"
                            danger
                            loading={rejectLoading}
                            onClick={handleReject}
                        >
                            Reject Link
                        </Button>
                    </div>
                }
            >
                <p className="text-sm text-slate-500 mb-4">
                    Please provide a reason for rejecting this link. The reason will be visible to the institution.
                </p>
                <Form form={rejectForm} layout="vertical">
                    <Form.Item
                        name="rejectReason"
                        label="Reject Reason"
                        rules={[{ required: true, message: "Please enter a reject reason." }]}
                    >
                        <Input.TextArea
                            rows={3}
                            placeholder="e.g., Link is broken, inappropriate content, etc."
                            className="rounded-lg"
                        />
                    </Form.Item>
                </Form>
            </Modal>
        </div>
    );
};

export default NotesLinksApprovalPage;