import dayjs from "dayjs";
import toast from "react-hot-toast";
import { ColumnsType } from "antd/es/table";
import React, { useEffect, useState } from "react";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import { useDebounce } from "@/hooks/useDebounce";
import { History, FileText, Clock, Trash2, Building, Search } from "lucide-react";
import { Card, Table, Pagination, Select, Spin, Empty, Tag, Button, Popconfirm, Tooltip, Input } from "antd";

interface IInstitution {
  id: string;
  institutionName: string;
}

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

const SharedHistory: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<any[]>([]);
  const [pagination, setPagination] = useState(paginationInitial);

  const [institutions, setInstitutions] = useState<IInstitution[]>([]);
  const [fetchingInstitutions, setFetchingInstitutions] = useState(false);

  const [filterFrom, setFilterFrom] = useState<string | undefined>(undefined);
  const [filterTo, setFilterTo] = useState<string | undefined>(undefined);
  const [filterType, setFilterType] = useState<string | undefined>(undefined);
  const [filterSubjectId, setFilterSubjectId] = useState<string | undefined>(undefined);
  const [filterExamId, setFilterExamId] = useState<string | undefined>(undefined);
  const [filterYear, setFilterYear] = useState<string | undefined>(undefined);
  const [searchQuery, setSearchQuery] = useState("");
  const debouncedSearch = useDebounce(searchQuery, 600);

  const [subjects, setSubjects] = useState<any[]>([]);
  const [loadingSubjects, setLoadingSubjects] = useState(false);
  const [exams, setExams] = useState<any[]>([]);
  const [loadingExams, setLoadingExams] = useState(false);

  useEffect(() => {
    (async () => {
      setFetchingInstitutions(true);
      try {
        const res = await API_Instance.get(API_Constants.users, {
          params: { role: "Institution", limit: 1000 },
        });
        setInstitutions(res.data.data || []);
      } catch {
        toast.error("Failed to load institutions");
      } finally {
        setFetchingInstitutions(false);
      }
    })();
  }, []);
  useEffect(() => {
    if (!filterFrom || filterType !== "TEST") {
      setSubjects([]);
      setFilterSubjectId(undefined);
      return;
    }
    (async () => {
      setLoadingSubjects(true);
      try {
        const res = await API_Instance.get(API_Constants.subjects, {
          params: { institutionId: filterFrom, limit: 1000 },
        });
        setSubjects(res.data.data || []);
      } catch {
      } finally {
        setLoadingSubjects(false);
      }
    })();
  }, [filterFrom, filterType]);

  useEffect(() => {
    if (!filterFrom || (filterType !== "PYQ" && filterType !== "MOCK_TEST")) {
      setExams([]);
      setFilterExamId(undefined);
      return;
    }
    (async () => {
      setLoadingExams(true);
      try {
        const res = await API_Instance.get(API_Constants.exams, {
          params: { institutionId: filterFrom, limit: 1000 },
        });
        setExams(res.data.data || []);
      } catch {
      } finally {
        setLoadingExams(false);
      }
    })();
  }, [filterFrom, filterType]);

  useEffect(() => {
    setPagination(paginationInitial);
  }, [filterFrom, filterTo, filterType, filterSubjectId, filterExamId, filterYear, debouncedSearch]);

  useEffect(() => {
    fetchHistory(pagination.page, pagination.limit);
  }, [filterFrom, filterTo, filterType, filterSubjectId, filterExamId, filterYear, debouncedSearch, pagination.page, pagination.limit]);

  const fetchHistory = async (page = 1, limit = 10) => {
    setLoading(true);
    try {
      const res = await API_Instance.get(API_Constants.sharedResourceHistory, {
        params: {
          page,
          limit,
          ...(filterFrom ? { fromInstitutionId: filterFrom } : {}),
          ...(filterTo ? { toInstitutionId: filterTo } : {}),
          ...(filterType ? { resourceType: filterType } : {}),
          ...(filterSubjectId ? { subjectId: filterSubjectId } : {}),
          ...(filterExamId ? { examId: filterExamId } : {}),
          ...(filterYear ? { year: filterYear } : {}),
          ...(debouncedSearch ? { search: debouncedSearch } : {}),
        },
      });
      setData(res.data.data || []);
      setPagination(res.data.meta || paginationInitial);
    } catch (e) {
      toast.error(getAxiosErrorMessage(e));
    } finally {
      setLoading(false);
    }
  };

  const removeSharedResource = async (record: any) => {
    if (!record?.id) return;

    try {
      await API_Instance.post(`${API_Constants.sharedResource}/remove`, {
        resourceType: record.type,
        sharedId: record.id,
      });
      toast.success("Removed shared resource successfully");
      fetchHistory(pagination.page, pagination.limit);
    } catch (err) {
      toast.error(getAxiosErrorMessage(err));
    }
  };

  const typeConfig: Record<string, { label: string; color: string; icon: React.ReactNode }> = {
    TEST: { label: "Test", color: "blue", icon: <FileText size={11} /> },
    PYQ: { label: "PYQ", color: "purple", icon: <Clock size={11} /> },
    MOCK_TEST: { label: "Mock Test", color: "gold", icon: <FileText size={11} /> },
  };

  const columns: ColumnsType<any> = [
    {
      title: "Title",
      key: "resourceName",
      width: "20%",
      render: (_: any, record: any) => (
        <div className="flex flex-col gap-1.5">
          <div
            className="font-semibold text-slate-700 line-clamp-2 max-w-xs"
            dangerouslySetInnerHTML={{ __html: `${record.resourceName || "—"}${record.type === "PYQ" && record.year ? ` (${record.year})` : ""}` }}
          />
          {record.type === "TEST" && record.subjectName && (
            <Tag color="green" className="flex w-fit py-0.5 items-center gap-1 text-xs">
              Subject: {record.subjectName}
            </Tag>
          )}
          {(record.type === "PYQ" || record.type === "MOCK_TEST") && record.examName && (
            <Tag color={record.type === "MOCK_TEST" ? "gold" : "volcano"} className="flex w-fit py-0.5 items-center gap-1 text-xs">
              Exam: {record.examName}
            </Tag>
          )}
        </div>
      ),
    },
    {
      title: "Type",
      dataIndex: "type",
      key: "type",
      width: "16.66%",
      render: (type) => {
        const cfg = typeConfig[type] || { label: type, color: "default", icon: null };
        return (
          <Tag color={cfg.color} className="flex w-fit items-center gap-1">
            {cfg.icon}
            {cfg.label}
          </Tag>
        );
      },
    },
    {
      title: "From Institute",
      dataIndex: "fromInstitution",
      key: "fromInstitution",
      width: "16.66%",
      render: (v) => <span className="text-sm text-slate-600">{v || "—"}</span>,
    },
    {
      title: "To Institute",
      dataIndex: "toInstitution",
      key: "toInstitution",
      width: "16.66%",
      render: (v) => <span className="text-sm text-slate-600">{v || "—"}</span>,
    },
    {
      title: "Shared Date",
      dataIndex: "sharedDate",
      key: "sharedDate",
      width: "16.66%",
      render: (v) => (
        <span className="text-xs text-slate-500">
          {dayjs(v).format("DD MMM YYYY, hh:mm A")}
        </span>
      ),
    },
    {
      title: "Actions",
      key: "actions",
      align: "right",
      width: "16.66%",
      render: (_v, record: any) => (
        <Tooltip title={!record.isRemovable ? "Cannot remove because students have already taken this test" : ""}>
          <div className="inline-block">
            <Popconfirm
              title="Remove shared resource"
              description="Are you sure you want to remove this resource?"
              onConfirm={() => removeSharedResource(record)}
              disabled={!record.isRemovable}
              okText="Yes"
              cancelText="No"
            >
              <Button
                type="text"
                danger
                icon={<Trash2 size={13} />}
                className={`text-xs px-3 py-1 rounded-md font-medium transition-all shadow-sm ${record.isRemovable ? "bg-red-100 text-red-700 border border-red-300 hover:bg-red-200" : "bg-gray-100 text-gray-400 pointer-events-none"}`}
                disabled={!record.isRemovable}
              >
                Remove
              </Button>
            </Popconfirm>
          </div>
        </Tooltip>
      ),
    },
  ];

  const institutionOptions = institutions.map((i) => ({
    label: i.institutionName,
    value: i.id,
  }));

  return (
    <div className="flex flex-col gap-4 px-4 py-6">
      {/* Page Header */}
      <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">
            <History className="text-blue-600" /> Shared History
          </h2>
          <p className="text-slate-500 text-sm mt-1">
            View all resources that have been shared across institutions.
          </p>
        </div>
      </div>

      <Card className="shadow-sm border border-slate-200 rounded-xl">
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div className="flex flex-col gap-1.5">
            <label className="text-sm font-semibold text-slate-600 flex items-center gap-1.5">
              <Building size={14} className="text-slate-400" />
              From Institution <span className="text-red-500">*</span>
            </label>
            <Select
              allowClear
              showSearch
              className="w-full"
              placeholder="Select source institution"
              loading={fetchingInstitutions}
              options={institutionOptions}
              value={filterFrom}
              onChange={(val) => {
                setFilterFrom(val);
                if (!val || val === filterTo) setFilterTo(undefined);
              }}
              filterOption={(input, option) =>
                (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
              }
            />
          </div>

          {/* To Institution — optional */}
          <div className="flex flex-col gap-1.5" title={!filterFrom ? "Select From Institution first" : undefined}>
            <label className="text-sm font-semibold text-slate-600 flex items-center gap-1.5">
              <Building size={14} className="text-slate-400" />
              To Institution
            </label>
            <Select
              allowClear
              showSearch
              disabled={!filterFrom}
              className="w-full"
              placeholder="Select target institution"
              loading={fetchingInstitutions}
              options={institutionOptions.filter((o) => o.value !== filterFrom)}
              value={filterTo}
              onChange={(val) => setFilterTo(val)}
              filterOption={(input, option) =>
                (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
              }
            />
          </div>

          {/* Resource Type */}
          <div className="flex flex-col gap-1.5">
            <label className="text-sm font-semibold text-slate-600">Resource Type</label>
            <Select
              allowClear
              className="w-full"
              placeholder="All Types"
              value={filterType}
              onChange={(val) => {
                setFilterType(val);
                setFilterSubjectId(undefined);
                setFilterExamId(undefined);
                setFilterYear(undefined);
                setSearchQuery("");
              }}
              options={[
                { label: "Test", value: "TEST" },
                { label: "PYQ", value: "PYQ" },
                { label: "Mock Test", value: "MOCK_TEST" },
              ]}
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <label className="text-sm font-semibold text-slate-600">Search</label>
            <Input
              placeholder="Search Title"
              prefix={<Search size={14} className="text-slate-400" />}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
          </div>

          {filterType === "TEST" && (
            <div className="flex flex-col gap-1.5" title={!filterFrom ? "Select From Institution to filter by Subject" : undefined}>
              <label className="text-sm font-semibold text-slate-600">Subject</label>
              <Select
                allowClear
                showSearch
                disabled={!filterFrom}
                className="w-full"
                placeholder="All Subjects"
                loading={loadingSubjects}
                value={filterSubjectId}
                onChange={(val) => setFilterSubjectId(val)}
                options={subjects.map((s) => ({ label: s.subjectName, value: s.id }))}
                filterOption={(input, option) =>
                  (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
                }
              />
            </div>
          )}

          {(filterType === "PYQ" || filterType === "MOCK_TEST") && (
            <div className="flex flex-col gap-1.5" title={!filterFrom ? "Select From Institution to filter by Exam" : undefined}>
              <label className="text-sm font-semibold text-slate-600">Exam</label>
              <Select
                allowClear
                showSearch
                disabled={!filterFrom}
                className="w-full"
                placeholder="All Exams"
                loading={loadingExams}
                value={filterExamId}
                onChange={(val) => setFilterExamId(val)}
                options={exams.map((e) => ({ label: e.examName, value: e.id }))}
                filterOption={(input, option) =>
                  (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
                }
              />
            </div>
          )}

          {filterType === "PYQ" && (
            <div className="flex flex-col gap-1.5" title={!filterFrom ? "Select From Institution to filter by Year" : undefined}>
              <label className="text-sm font-semibold text-slate-600">Year</label>
              <Select
                allowClear
                showSearch
                disabled={!filterFrom}
                className="w-full"
                placeholder="Filter by Year"
                value={filterYear}
                onChange={(val) => setFilterYear(val)}
                options={Array.from({ length: 30 }, (_, i) => {
                  const y = new Date().getFullYear() - i;
                  return { label: String(y), value: String(y) };
                })}
              />
            </div>
          )}
        </div>
      </Card>

      <Card className="shadow-sm border border-slate-200 rounded-xl">
        {filterFrom && (
          <div className="flex justify-end mb-4 text-slate-500 text-sm">
            Total:{" "}
            <span className="font-semibold text-slate-800 ml-1">{pagination.total}</span>
          </div>
        )}

        <Spin spinning={loading}>
          {data.length === 0 && !loading ? (
            <div className="min-h-[200px] flex items-center justify-center">
              <Empty
                description={
                  filterTo || filterType
                    ? "No history found for selected filters"
                    : "No shared resources history for this institution"
                }
              />
            </div>
          ) : (
            <>
              <Table
                columns={columns}
                dataSource={data}
                rowKey="id"
                pagination={false}
                scroll={{ x: 800 }}
                className="border border-slate-100 rounded-lg overflow-hidden"
              />

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

export default SharedHistory;