"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  MdSearch,
  MdEvent,
  MdFilterList,
  MdReportProblem,
  MdArrowBack,
  MdArrowForward,
  MdSwapHoriz,
} from "react-icons/md";
import toast from "react-hot-toast";
import { discrepanciesService } from "@/services/api";
import {
  Discrepancy,
  DiscrepancyConditionFilter,
  DiscrepancyListMeta,
  DiscrepancyStatusFilter,
} from "@/types/discrepancy";
import { useAuth } from "@/contexts/AuthContext";
import DiscrepancyCard from "./DiscrepancyCard";
import TextInputModal from "@/components/ui/TextInputModal";
import DateFilterPopover from "@/components/ui/DateFilterPopover";
import DiscrepanciesFilterPopover from "./DiscrepanciesFilterPopover";

interface DiscrepanciesPageProps {
  /** Builder for the shipment detail link from a shipment id (role-specific). */
  shipmentLinkPath: (shipmentId: number) => string;
  /** Builder for the PO detail link from a PO id (role-specific). */
  purchaseOrderLinkPath: (poId: number) => string;
  /** Link to the item-level discrepancies page so the user can switch views. */
  itemDiscrepanciesPath: string;
}

const DEFAULT_LIMIT = 10;

const DiscrepanciesPage: React.FC<DiscrepanciesPageProps> = ({
  shipmentLinkPath,
  purchaseOrderLinkPath,
  itemDiscrepanciesPath,
}) => {
  const { isAdmin } = useAuth();
  const canResolve = isAdmin();

  const [discrepancies, setDiscrepancies] = useState<Discrepancy[]>([]);
  const [meta, setMeta] = useState<DiscrepancyListMeta>({
    currentPage: 1,
    itemsPerPage: DEFAULT_LIMIT,
    totalItems: 0,
    totalPages: 1,
    hasNextPage: false,
    hasPreviousPage: false,
  });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [statusFilter, setStatusFilter] =
    useState<DiscrepancyStatusFilter>("active");
  const [conditionFilter, setConditionFilter] =
    useState<DiscrepancyConditionFilter>("all");
  const [search, setSearch] = useState("");
  const [searchInput, setSearchInput] = useState("");
  const [startDate, setStartDate] = useState<string | null>(null);
  const [endDate, setEndDate] = useState<string | null>(null);
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [isDateFilterOpen, setIsDateFilterOpen] = useState(false);

  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(DEFAULT_LIMIT);

  // Modal state
  const [resolveTarget, setResolveTarget] = useState<Discrepancy | null>(null);
  const [reopenTarget, setReopenTarget] = useState<Discrepancy | null>(null);

  const fetch = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response = await discrepanciesService.list({
        page,
        limit,
        status: statusFilter,
        condition: conditionFilter,
        search: search || undefined,
        startDate: startDate || undefined,
        endDate: endDate || undefined,
      });
      setDiscrepancies(response.data.data || []);
      setMeta(response.data.meta);
    } catch (err: any) {
      console.error("Failed to fetch discrepancies", err);
      setError(
        err.response?.data?.message ||
          "Failed to load discrepancies. Please try again."
      );
    } finally {
      setLoading(false);
    }
  }, [
    page,
    limit,
    statusFilter,
    conditionFilter,
    search,
    startDate,
    endDate,
  ]);

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

  // Debounced search
  useEffect(() => {
    const t = setTimeout(() => {
      if (searchInput !== search) {
        setSearch(searchInput);
        setPage(1);
      }
    }, 350);
    return () => clearTimeout(t);
  }, [searchInput, search]);

  const dateFilterCount = useMemo(
    () => (startDate ? 1 : 0) + (endDate ? 1 : 0),
    [startDate, endDate]
  );

  // Default filter values: status=active (the only "interesting" view), condition=all.
  // Anything different counts toward the badge on the Filter button.
  const filterCount = useMemo(() => {
    let count = 0;
    if (statusFilter !== "active") count += 1;
    if (conditionFilter !== "all") count += 1;
    return count;
  }, [statusFilter, conditionFilter]);

  const handleApplyFilters = (filters: {
    status: DiscrepancyStatusFilter;
    condition: DiscrepancyConditionFilter;
  }) => {
    setStatusFilter(filters.status);
    setConditionFilter(filters.condition);
    setPage(1);
  };

  const handleApplyDateFilter = (start: string | null, end: string | null) => {
    setStartDate(start);
    setEndDate(end);
    setPage(1);
  };

  const handleResolveSubmit = async (note: string) => {
    if (!resolveTarget) return;
    try {
      await discrepanciesService.resolve(resolveTarget.id, note);
      toast.success("Discrepancy resolved.");
      setResolveTarget(null);
      fetch();
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Failed to resolve discrepancy."
      );
    }
  };

  const handleReopenSubmit = async (note: string) => {
    if (!reopenTarget) return;
    try {
      await discrepanciesService.reopen(reopenTarget.id, note);
      toast.success("Discrepancy reopened.");
      setReopenTarget(null);
      fetch();
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Failed to reopen discrepancy."
      );
    }
  };

  const startItem = meta.totalItems === 0 ? 0 : (page - 1) * limit + 1;
  const endItem = Math.min(page * limit, meta.totalItems);

  return (
    <>
      {/* Sticky Header */}
      <div className="sticky top-0 z-30 bg-gradient-to-l from-white to-[#DFF9FF] shadow-sm border-b border-gray-200">
        <div className="px-4 md:px-6 py-4 flex items-center justify-between flex-wrap gap-3">
          <div className="flex items-center gap-3 flex-wrap">
            <h1 className="text-xl md:text-2xl font-bold text-gray-800">
              Pallet Discrepancies
            </h1>
            <Link
              href={itemDiscrepanciesPath}
              className="inline-flex items-center gap-1 text-sm text-[#3997E0] hover:underline"
            >
              <MdSwapHoriz size={16} />
              Item Discrepancies
            </Link>
          </div>
        </div>
      </div>

      <div className="m-4 md:m-6">
        <div className="bg-white rounded-lg shadow-[0px_4px_34px_0px_rgba(0,59,113,0.16)]">
          {/* Search + Filters — same layout as the shipments list */}
          <div className="p-4 md:p-6 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0 md:space-x-4">
            <div className="flex items-center bg-gray-100 p-2 rounded-md w-full md:w-1/3">
              <MdSearch size={20} color="#6B7280" className="mr-2" />
              <input
                type="text"
                placeholder="Search shipment, barcode, or description..."
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                className="bg-transparent outline-none w-full text-sm text-gray-700 placeholder-gray-500"
              />
            </div>
            <div className="flex items-center space-x-4">
              <button
                className="flex items-center text-gray-600 hover:text-gray-800 text-sm bg-gray-100 p-2 rounded-md relative"
                onClick={() => setIsFilterOpen(true)}
              >
                <MdFilterList size={20} className="mr-2" />
                Filters
                {filterCount > 0 && (
                  <span className="absolute -top-2 -right-2 bg-blue-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
                    {filterCount}
                  </span>
                )}
              </button>
              <button
                className="flex items-center text-gray-600 hover:text-gray-800 text-sm bg-gray-100 p-2 rounded-md relative"
                onClick={() => setIsDateFilterOpen(true)}
              >
                <MdEvent size={20} className="mr-2" />
                Date Filter
                {dateFilterCount > 0 && (
                  <span className="absolute -top-2 -right-2 bg-blue-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
                    {dateFilterCount}
                  </span>
                )}
              </button>
            </div>
          </div>

          {/* Body */}
          {loading ? (
            <div className="flex justify-center items-center py-16">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mr-3" />
              <span className="text-gray-600">Loading discrepancies...</span>
            </div>
          ) : error ? (
            <div className="p-6 bg-red-100 text-red-700 m-4 rounded-md">
              <p className="font-medium">Error</p>
              <p>{error}</p>
            </div>
          ) : discrepancies.length === 0 ? (
            <div className="p-12 text-center">
              <MdReportProblem className="h-16 w-16 text-gray-300 mx-auto mb-4" />
              <p className="text-gray-500 text-lg">No discrepancies found</p>
              <p className="text-gray-400 text-sm">
                {statusFilter === "active"
                  ? "Nothing currently needs follow-up."
                  : "No records match your filters."}
              </p>
            </div>
          ) : (
            <div className="px-4 md:px-6 pb-6 space-y-4">
              {discrepancies.map((d) => (
                <DiscrepancyCard
                  key={d.id}
                  discrepancy={d}
                  canResolve={canResolve}
                  onResolve={setResolveTarget}
                  onReopen={setReopenTarget}
                  shipmentLinkPath={shipmentLinkPath}
                  purchaseOrderLinkPath={purchaseOrderLinkPath}
                  defaultCollapsed={true}
                />
              ))}
            </div>
          )}

          {/* Pagination */}
          {!loading && !error && discrepancies.length > 0 && (
            <div className="px-4 lg:px-6 py-4 border-t border-gray-200 flex flex-col lg:flex-row lg:justify-between lg:items-center gap-3">
              <div className="flex items-center gap-2 text-sm text-gray-600">
                <select
                  value={limit}
                  onChange={(e) => {
                    setLimit(Number(e.target.value));
                    setPage(1);
                  }}
                  className="border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500 bg-white text-sm"
                >
                  <option value={10}>10</option>
                  <option value={20}>20</option>
                  <option value={50}>50</option>
                </select>
                <span>per page</span>
                <span className="ml-3">
                  {startItem}-{endItem} of {meta.totalItems}
                </span>
              </div>
              <div className="flex items-center gap-1">
                <button
                  onClick={() => setPage((p) => Math.max(1, p - 1))}
                  disabled={!meta.hasPreviousPage}
                  className="px-3 py-1.5 text-sm rounded-md border border-gray-300 text-gray-700 hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed inline-flex items-center gap-1"
                >
                  <MdArrowBack size={16} />
                  Prev
                </button>
                <span className="text-sm text-gray-600 px-2">
                  Page {meta.currentPage} of {meta.totalPages}
                </span>
                <button
                  onClick={() =>
                    setPage((p) => Math.min(meta.totalPages, p + 1))
                  }
                  disabled={!meta.hasNextPage}
                  className="px-3 py-1.5 text-sm rounded-md border border-gray-300 text-gray-700 hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed inline-flex items-center gap-1"
                >
                  Next
                  <MdArrowForward size={16} />
                </button>
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Resolve Modal */}
      {resolveTarget && (
        <TextInputModal
          isOpen={true}
          onClose={() => setResolveTarget(null)}
          onConfirm={handleResolveSubmit}
          title="Mark Discrepancy Resolved"
          description={`Pallet #${resolveTarget.palletNumber} on ${
            resolveTarget.shipmentNumber || "this shipment"
          }. Note how the discrepancy was handled (refund, replacement, written off, etc.).`}
          placeholder="e.g. Replacement scheduled in shipment SH-1234"
          confirmText="Mark Resolved"
          cancelText="Cancel"
          required={true}
          multiline={true}
        />
      )}

      {/* Reopen Modal */}
      {reopenTarget && (
        <TextInputModal
          isOpen={true}
          onClose={() => setReopenTarget(null)}
          onConfirm={handleReopenSubmit}
          title="Reopen Discrepancy"
          description={`Pallet #${reopenTarget.palletNumber} on ${
            reopenTarget.shipmentNumber || "this shipment"
          }. Add a note explaining why this is being reopened.`}
          placeholder="e.g. Replacement never arrived"
          confirmText="Reopen"
          cancelText="Cancel"
          required={true}
          multiline={true}
        />
      )}

      {/* Filters Popover — status + condition */}
      <DiscrepanciesFilterPopover
        isOpen={isFilterOpen}
        onClose={() => setIsFilterOpen(false)}
        onApply={handleApplyFilters}
        initialFilters={{
          status: statusFilter,
          condition: conditionFilter,
        }}
      />

      {/* Date Filter — applies to when the discrepancy was first reported */}
      <DateFilterPopover
        isOpen={isDateFilterOpen}
        onClose={() => setIsDateFilterOpen(false)}
        onApply={handleApplyDateFilter}
        initialStartDate={startDate}
        initialEndDate={endDate}
        showDateRangeInfo={true}
      />
    </>
  );
};

export default DiscrepanciesPage;
