"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  MdSearch,
  MdEvent,
  MdFilterList,
  MdReportProblem,
  MdArrowBack,
  MdArrowForward,
  MdQrCodeScanner,
  MdSwapHoriz,
} from "react-icons/md";
import toast from "react-hot-toast";
import { itemDiscrepanciesService } from "@/services/api";
import {
  ItemDiscrepancy,
  ItemDiscrepancyListMeta,
  ShipmentPalletItemCondition,
} from "@/types/item-discrepancy";
import {
  DiscrepancyConditionFilter,
  DiscrepancyStatusFilter,
} from "@/types/discrepancy";
import { useAuth } from "@/contexts/AuthContext";
import ItemDiscrepancyCard from "./ItemDiscrepancyCard";
import TextInputModal from "@/components/ui/TextInputModal";
import ConfirmationModal from "@/components/ui/ConfirmationModal";
import MarkDamageModal from "@/components/ui/MarkDamageModal";
import DateFilterPopover from "@/components/ui/DateFilterPopover";
import BarcodeScanner from "@/components/ui/BarcodeScanner";
import DiscrepanciesFilterPopover from "./DiscrepanciesFilterPopover";

interface ItemDiscrepanciesPageProps {
  shipmentLinkPath: (shipmentId: number) => string;
  purchaseOrderLinkPath: (poId: number) => string;
  /** Link to the pallet-level discrepancies page so the user can switch views. */
  palletDiscrepanciesPath: string;
}

const DEFAULT_LIMIT = 10;

const ItemDiscrepanciesPage: React.FC<ItemDiscrepanciesPageProps> = ({
  shipmentLinkPath,
  purchaseOrderLinkPath,
  palletDiscrepanciesPath,
}) => {
  const { isAdmin } = useAuth();
  // Admins are the only role that physically handles items at the warehouse,
  // so reporting / clearing / resolving are all gated on isAdmin().
  const canResolve = isAdmin();
  const canReport = isAdmin();

  const [items, setItems] = useState<ItemDiscrepancy[]>([]);
  const [meta, setMeta] = useState<ItemDiscrepancyListMeta>({
    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);

  // Modals
  const [resolveTarget, setResolveTarget] = useState<ItemDiscrepancy | null>(
    null
  );
  const [reopenTarget, setReopenTarget] = useState<ItemDiscrepancy | null>(
    null
  );
  const [clearTarget, setClearTarget] = useState<ItemDiscrepancy | null>(null);

  // Scan-to-report flow state
  const [isScanModalOpen, setIsScanModalOpen] = useState(false);
  const [scanInput, setScanInput] = useState("");
  const [scanLookupLoading, setScanLookupLoading] = useState(false);
  const [scanLookupResult, setScanLookupResult] =
    useState<ItemDiscrepancy | null>(null);
  const [damageReportTarget, setDamageReportTarget] =
    useState<ItemDiscrepancy | null>(null);
  const [missingReportTarget, setMissingReportTarget] =
    useState<ItemDiscrepancy | null>(null);
  const [isSubmittingReport, setIsSubmittingReport] = useState(false);

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

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

  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]
  );

  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 itemDiscrepanciesService.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 itemDiscrepanciesService.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 handleClearConfirm = async () => {
    if (!clearTarget) return;
    try {
      await itemDiscrepanciesService.clear(clearTarget.id);
      toast.success("Item marked OK and stock restored.");
      setClearTarget(null);
      fetch();
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Failed to clear discrepancy."
      );
    }
  };

  // Scan-to-report flow
  const handleOpenScanModal = () => {
    setScanInput("");
    setScanLookupResult(null);
    setIsScanModalOpen(true);
  };

  const lookupBarcode = async (rawCode: string) => {
    const code = rawCode.trim();
    if (!code) {
      toast.error("Enter or scan a barcode.");
      return;
    }
    try {
      setScanLookupLoading(true);
      setScanInput(code);
      const response = await itemDiscrepanciesService.lookupByBarcode(code);
      setScanLookupResult(response.data);
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Barcode not found in any shipment."
      );
      setScanLookupResult(null);
    } finally {
      setScanLookupLoading(false);
    }
  };

  const handleStartDamageReport = (item: ItemDiscrepancy) => {
    setIsScanModalOpen(false);
    setDamageReportTarget(item);
  };

  const handleStartMissingReport = (item: ItemDiscrepancy) => {
    setIsScanModalOpen(false);
    setMissingReportTarget(item);
  };

  const handleDamageReportSubmit = async (
    description: string,
    images: string[]
  ) => {
    if (!damageReportTarget) return;
    try {
      setIsSubmittingReport(true);
      await itemDiscrepanciesService.reportDamaged(
        damageReportTarget.id,
        description,
        images
      );
      toast.success("Item reported as damaged.");
      setDamageReportTarget(null);
      fetch();
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Failed to report damaged item."
      );
    } finally {
      setIsSubmittingReport(false);
    }
  };

  const handleConfirmMissingReport = async () => {
    if (!missingReportTarget) return;
    try {
      await itemDiscrepanciesService.reportMissing(missingReportTarget.id);
      toast.success("Item reported as missing.");
      setMissingReportTarget(null);
      fetch();
    } catch (err: any) {
      toast.error(
        err.response?.data?.message || "Failed to report missing item."
      );
    }
  };

  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 flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
          <div className="flex items-center gap-3 flex-wrap">
            <h1 className="text-xl md:text-2xl font-bold text-gray-800">
              Item Discrepancies
            </h1>
            <Link
              href={palletDiscrepanciesPath}
              className="inline-flex items-center gap-1 text-sm text-[#3997E0] hover:underline"
            >
              <MdSwapHoriz size={16} />
              Pallet Discrepancies
            </Link>
          </div>
          {canReport && (
            <button
              onClick={handleOpenScanModal}
              className="inline-flex items-center gap-2 bg-[#3997E0] text-white px-4 py-2 rounded-xl text-sm hover:bg-blue-700"
            >
              <MdQrCodeScanner size={18} />
              Report by Barcode
            </button>
          )}
        </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 */}
          <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 item 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>
          ) : items.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 item 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">
              {items.map((d) => (
                <ItemDiscrepancyCard
                  key={d.id}
                  discrepancy={d}
                  canResolve={canResolve}
                  onResolve={setResolveTarget}
                  onReopen={setReopenTarget}
                  onClear={canResolve ? setClearTarget : undefined}
                  shipmentLinkPath={shipmentLinkPath}
                  purchaseOrderLinkPath={purchaseOrderLinkPath}
                  defaultCollapsed={true}
                />
              ))}
            </div>
          )}

          {/* Pagination */}
          {!loading && !error && items.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={`${resolveTarget.productName} on Pallet #${resolveTarget.palletNumber}. Note how it was handled.`}
          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={`${reopenTarget.productName} on Pallet #${reopenTarget.palletNumber}. Add a note explaining why.`}
          placeholder="e.g. Replacement never arrived"
          confirmText="Reopen"
          cancelText="Cancel"
          required={true}
          multiline={true}
        />
      )}

      {/* Clear (Mark OK) Confirmation */}
      {clearTarget && (
        <ConfirmationModal
          isOpen={true}
          onClose={() => setClearTarget(null)}
          onConfirm={handleClearConfirm}
          title="Mark Item OK"
          description={`This will revert ${clearTarget.productName} (barcode ${
            clearTarget.barcode || "—"
          }) back to OK and restore stock by 1. The discrepancy record will be removed.`}
          iconColor="#10B981"
          iconContainerColor="#D1FAE5"
          confirmText="Mark OK"
          cancelText="Cancel"
          autoCloseOnConfirm={false}
        />
      )}

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

      {/* Date Filter */}
      <DateFilterPopover
        isOpen={isDateFilterOpen}
        onClose={() => setIsDateFilterOpen(false)}
        onApply={handleApplyDateFilter}
        initialStartDate={startDate}
        initialEndDate={endDate}
        showDateRangeInfo={true}
      />

      {/* Scan / Lookup Modal */}
      {isScanModalOpen && (
        <div className="fixed inset-0 z-50 overflow-y-auto">
          <div className="flex min-h-screen items-center justify-center p-4">
            <div
              className="fixed inset-0 bg-black bg-opacity-30"
              onClick={() => setIsScanModalOpen(false)}
            />
            <div className="relative w-full max-w-lg transform rounded-lg bg-white p-6 shadow-xl max-h-[90vh] overflow-y-auto">
              <h3 className="text-lg font-bold text-gray-800 mb-2">
                Report Item by Barcode
              </h3>
              <p className="text-sm text-gray-500 mb-4">
                Scan with the camera or enter a barcode manually. Then choose
                Damaged or Missing.
              </p>

              <BarcodeScanner
                onBarcodeDetected={lookupBarcode}
                scannerId="item-discrepancy-scanner"
                title="Scan The Barcode On Item"
                manualPlaceholder="Enter Item Barcode"
                manualButtonText="Lookup"
              />

              {scanLookupLoading && (
                <div className="text-sm text-gray-500 mt-3 flex items-center gap-2">
                  <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500" />
                  Looking up barcode {scanInput}...
                </div>
              )}

              {scanLookupResult && (
                <div className="border border-gray-200 rounded-md p-3 mt-4 bg-gray-50">
                  <div className="text-sm font-semibold text-gray-800 mb-1">
                    {scanLookupResult.productName}
                  </div>
                  <div className="text-xs text-gray-600">
                    Pallet #{scanLookupResult.palletNumber} ·{" "}
                    {scanLookupResult.shipmentNumber} ·{" "}
                    {scanLookupResult.purchaseOrderNumber}
                  </div>
                  <div className="text-xs text-gray-500 font-mono mt-1">
                    {scanLookupResult.barcode}
                  </div>
                  {scanLookupResult.itemCondition !==
                    ShipmentPalletItemCondition.OK && (
                    <div className="text-xs text-amber-700 mt-2">
                      Already flagged as {scanLookupResult.itemCondition}.
                    </div>
                  )}
                </div>
              )}

              <div className="flex justify-between items-center pt-4 mt-4 border-t border-gray-100">
                <button
                  onClick={() => setIsScanModalOpen(false)}
                  className="text-sm text-gray-600 hover:text-gray-800"
                >
                  Cancel
                </button>
                {scanLookupResult &&
                  scanLookupResult.itemCondition ===
                    ShipmentPalletItemCondition.OK && (
                    <div className="flex gap-2">
                      <button
                        onClick={() =>
                          handleStartMissingReport(scanLookupResult)
                        }
                        className="inline-flex items-center gap-1 px-3 py-1.5 text-sm rounded-md border border-red-300 text-red-700 hover:bg-red-50"
                      >
                        Mark Missing
                      </button>
                      <button
                        onClick={() => handleStartDamageReport(scanLookupResult)}
                        className="inline-flex items-center gap-1 px-3 py-1.5 text-sm rounded-md bg-amber-500 text-white hover:bg-amber-600"
                      >
                        Mark Damaged
                      </button>
                    </div>
                  )}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Damage Report Modal (item-level) */}
      {damageReportTarget && (
        <MarkDamageModal
          isOpen={true}
          onClose={() => setDamageReportTarget(null)}
          onSubmit={handleDamageReportSubmit}
          productName={damageReportTarget.productName}
          barcodeNumber={damageReportTarget.barcode || ""}
          isSubmitting={isSubmittingReport}
        />
      )}

      {/* Missing Report Confirmation */}
      {missingReportTarget && (
        <ConfirmationModal
          isOpen={true}
          onClose={() => setMissingReportTarget(null)}
          onConfirm={handleConfirmMissingReport}
          title="Mark Item Missing"
          description={`Mark ${missingReportTarget.productName} (barcode ${
            missingReportTarget.barcode || "—"
          }) as missing? Stock will be reduced by 1.`}
          iconColor="#DC2626"
          iconContainerColor="#FEE2E2"
          confirmText="Yes, Mark Missing"
          cancelText="Cancel"
          autoCloseOnConfirm={false}
        />
      )}
    </>
  );
};

export default ItemDiscrepanciesPage;
