﻿// react
import React, { useState, useEffect } from "react";
// third-party
import { useRouter } from "next/router";
// application
import AdminLayout from "~/admin/components/AdminLayout";
import ProtectedRoute from "~/admin/components/ProtectedRoute";
import ProductList from "~/admin/components/products/ProductList";
import ProductForm from "~/admin/components/products/ProductForm";
import { IProduct } from "~/admin/interfaces/product";
import { productsApi } from "~/admin/services/productsApi";
import { toast } from "react-toastify";
import { IModel } from "~/admin/interfaces/vehicle";
import { vehiclesApi } from "~/admin/services/vehiclesApi";
import AppLink from "~/admin/components/AppLink";

/**
 * Desplegable de filtro reutilizable (mismo patrón visual que el filtro de modelo).
 */
function FilterDropdown({
  icon,
  title,
  active,
  open,
  onToggle,
  onClose,
  selectLabel,
  value,
  options,
  onChange,
}: {
  icon: string;
  title: string;
  active: boolean;
  open: boolean;
  onToggle: () => void;
  onClose: () => void;
  selectLabel: string;
  value: string;
  options: { value: string; label: string }[];
  onChange: (value: string) => void;
}) {
  return (
    <div className="productos-search__model">
      <button
        type="button"
        className={`productos-search__model-btn ${active ? "productos-search__model-btn--active" : ""}`}
        onClick={onToggle}
      >
        <i className={`${icon} mr-1`} />
        {title}
        <i
          className={`fas fa-chevron-down ml-2 productos-search__model-chevron ${
            open ? "productos-search__model-chevron--open" : ""
          }`}
        />
      </button>
      {open && (
        <div className="productos-search__model-panel">
          <label className="productos-search__model-label">{selectLabel}</label>
          <select
            className="form-control productos-search__model-select"
            value={value}
            onChange={(e) => {
              onChange(e.target.value);
              onClose();
            }}
          >
            {options.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        </div>
      )}
    </div>
  );
}

function ProductosPage() {
  const router = useRouter();
  const [products, setProducts] = useState<IProduct[]>([]);
  const [allProducts, setAllProducts] = useState<IProduct[]>([]);
  const [selectedProductIds, setSelectedProductIds] = useState<number[]>([]);
  const [selectAllMode, setSelectAllMode] = useState(false);
  const [excludedProductIds, setExcludedProductIds] = useState<number[]>([]);
  const [editingProduct, setEditingProduct] = useState<IProduct | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [loading, setLoading] = useState(true);
  const [searchLoading, setSearchLoading] = useState(false);
  const [models, setModels] = useState<IModel[]>([]);
  const [showModelFilter, setShowModelFilter] = useState(false);
  const [showStatusFilter, setShowStatusFilter] = useState(false);
  const [showImageFilter, setShowImageFilter] = useState(false);
  const [showDataFilter, setShowDataFilter] = useState(false);
  const [appliedModelFilter, setAppliedModelFilter] = useState<number | null>(null);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalProductsInDb, setTotalProductsInDb] = useState(0);
  const [totalFiltered, setTotalFiltered] = useState(0);
  const [searchTerm, setSearchTerm] = useState("");

  // El filtro de estado vive SOLO en la URL (?status=0/1): única fuente de verdad.
  const urlStatus =
    router.query.status === "1"
      ? 1
      : router.query.status === "0"
      ? 0
      : undefined;

  // Filtro de completitud vive SOLO en la URL (?filter=...):
  // con_imagen | sin_imagen | sin_categoria | sin_reference | incompletos
  const urlFilter = typeof router.query.filter === "string" ? router.query.filter : "";
  const urlHasImage =
    urlFilter === "con_imagen" ? 1 : urlFilter === "sin_imagen" ? 0 : undefined;
  const urlMissing =
    urlFilter === "sin_categoria"
      ? "categoria"
      : urlFilter === "sin_reference"
      ? "reference"
      : urlFilter === "incompletos"
      ? "any"
      : undefined;
  const hasSpecialFilter = urlHasImage !== undefined || Boolean(urlMissing);

  // Navega manteniendo status y filter coexistentes en la URL
  const pushQuery = (updates: Record<string, string | undefined>) => {
    const query: Record<string, string> = {};
    if (urlStatus !== undefined) query.status = String(urlStatus);
    if (urlFilter) query.filter = urlFilter;
    for (const [key, value] of Object.entries(updates)) {
      if (value === undefined || value === "") {
        delete query[key];
      } else {
        query[key] = value;
      }
    }
    router.push({ pathname: "/admin/productos", query }, undefined, { shallow: false });
  };

  const clearSelection = () => {
    setSelectAllMode(false);
    setExcludedProductIds([]);
    setSelectedProductIds([]);
  };

  const getSelectionScopeTotal = () => {
    if (searchTerm.trim()) {
      return products.filter((p) => typeof p.id === "number").length;
    }
    if (appliedModelFilter || hasSpecialFilter) {
      return totalFiltered;
    }
    return totalProductsInDb;
  };

  const isProductSelected = (id: number) =>
    selectAllMode
      ? !excludedProductIds.includes(id)
      : selectedProductIds.includes(id);

  const getSelectedCount = () => {
    if (selectAllMode) {
      return Math.max(0, getSelectionScopeTotal() - excludedProductIds.length);
    }
    return selectedProductIds.length;
  };

  const loadProducts = async () => {
    try {
      setLoading(true);
      const res = await productsApi.getAll(
        page,
        20,
        undefined,
        undefined,
        urlStatus,
        appliedModelFilter,
        urlHasImage,
        urlMissing
      );

      setAllProducts(res.data);
      setProducts(res.data);
      setTotalProductsInDb(res.count);
      setTotalFiltered(res.totalFiltered ?? res.data.length);
      if (res.pagination) {
        setTotalPages(res.pagination.total_pages);
      }
    } catch (error: any) {
      toast.error(error.message || "Error al cargar productos");
    } finally {
      setLoading(false);
    }
  };

  const handleSearchSubmit = async () => {
    const term = searchTerm.trim();
    if (!term) {
      setProducts(allProducts);
      return;
    }
    try {
      setSearchLoading(true);
      clearSelection();
      const res = await productsApi.search(term, appliedModelFilter);
      setProducts(res.data);
    } catch (error: any) {
      toast.error(error.message || "Error al buscar productos");
      setProducts([]);
    } finally {
      setSearchLoading(false);
    }
  };

  const handleClearSearch = () => {
    setSearchTerm("");
    setProducts(allProducts);
    clearSelection();
  };

  const handleCreate = () => {
    setEditingProduct(null);
    setShowForm(true);
  };

  const handleEdit = async (product: IProduct) => {
    try {
      setEditingProduct(product);
      setShowForm(true);
    } catch (error: any) {
      toast.error(error.message || "Error al cargar producto");
    }
  };

  const handleCreateProductApi = async (formData: FormData) => {
    try {
      if (editingProduct?.id) {
        await productsApi.update(editingProduct.id, formData);
        toast.success("Producto actualizado exitosamente");
      } else {
        await productsApi.create(formData);
        toast.success("Producto creado exitosamente");
      }
      setShowForm(false);
      setEditingProduct(null);

      loadProducts();
    } catch (error: any) {
      toast.error(error.message || "Error al guardar producto");
    }
  };

  const handleDelete = async (id: number) => {
    if (!confirm("¿Estás seguro de eliminar este producto?")) {
      return;
    }

    try {
      await productsApi.delete(id);
      toast.success("Producto eliminado exitosamente");
      if (selectAllMode) {
        setExcludedProductIds((prev) => prev.filter((x) => x !== id));
      } else {
        setSelectedProductIds((prev) => prev.filter((x) => x !== id));
      }
      loadProducts();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar producto");
    }
  };

  const resolveSelectedIdsForDelete = async (): Promise<number[]> => {
    if (!selectAllMode) {
      return selectedProductIds;
    }

    const allIds = await productsApi.fetchAllIds(
      appliedModelFilter,
      urlStatus,
      urlHasImage,
      urlMissing
    );
    const excluded = new Set(excludedProductIds);
    return allIds.filter((id) => !excluded.has(id));
  };

  const handleDeleteSelected = async () => {
    const count = getSelectedCount();
    if (count === 0) return;
    const msg = `¿Eliminar ${count} producto${count !== 1 ? "s" : ""} seleccionado${count !== 1 ? "s" : ""}?`;
    if (!confirm(msg)) return;
    try {
      const idsToDelete = await resolveSelectedIdsForDelete();
      await Promise.all(idsToDelete.map((id) => productsApi.delete(id)));
      toast.success("Productos seleccionados eliminados");
      clearSelection();
      await loadProducts();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar productos seleccionados");
    }
  };

  const handleDeleteAll = async () => {
    if (
      !confirm(
        "¿Eliminar TODOS los productos? Esta acción no se puede deshacer."
      )
    ) {
      return;
    }

    try {
      const affected = await productsApi.deleteAll();
      toast.success(
        affected > 0
          ? `Se eliminaron ${affected} producto${affected !== 1 ? "s" : ""}`
          : "No había productos para eliminar"
      );
      setPage(1);
      clearSelection();
      await loadProducts();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar todos los productos");
    }
  };

  const handleToggleProduct = (id: number, checked: boolean) => {
    if (selectAllMode) {
      setExcludedProductIds((prev) => {
        if (checked) {
          return prev.filter((x) => x !== id);
        }
        if (prev.includes(id)) return prev;
        return [...prev, id];
      });
      return;
    }

    setSelectedProductIds((prev) => {
      if (checked) {
        if (prev.includes(id)) return prev;
        return [...prev, id];
      }
      return prev.filter((x) => x !== id);
    });
  };

  const handleToggleAllVisible = (ids: number[], checked: boolean) => {
    if (!checked) {
      clearSelection();
      return;
    }

    if (searchTerm.trim()) {
      setSelectAllMode(false);
      setExcludedProductIds([]);
      setSelectedProductIds(Array.from(new Set(ids)));
      return;
    }

    setSelectAllMode(true);
    setExcludedProductIds([]);
    setSelectedProductIds([]);
  };

  const handleCancel = () => {
    setShowForm(false);
    setEditingProduct(null);
  };

  const loadModels = async () => {
    try {
      const data = await vehiclesApi.getAllModels(true);
      setModels(data);
    } catch (error: any) {
      toast.error(error.message || "Error al cargar modelos");
    }
  };

  // Reset de paginación/selección cuando cambia un filtro en la URL
  useEffect(() => {
    clearSelection();
    setSearchTerm("");
    setPage(1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [urlStatus, urlFilter]);

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

  // Carga de productos (espera a que Next.js tenga el query de la URL listo)
  useEffect(() => {
    if (!router.isReady) return;
    loadProducts();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [page, appliedModelFilter, urlStatus, urlHasImage, urlMissing, router.isReady]);

  const allProductsSelected =
    selectAllMode &&
    excludedProductIds.length === 0 &&
    !searchTerm.trim() &&
    !appliedModelFilter &&
    !hasSpecialFilter &&
    totalProductsInDb > 0;
  const selectedCount = getSelectedCount();
  const hasPartialSelection = selectedCount > 0 && !allProductsSelected;

  if (loading && products.length === 0) {
    return (
      <ProtectedRoute>
        <AdminLayout>
          <div className="text-center py-5">
            <div className="spinner-border" role="status">
              <span className="sr-only">Cargando...</span>
            </div>
          </div>
        </AdminLayout>
      </ProtectedRoute>
    );
  }

  return (
    <ProtectedRoute>
      <AdminLayout>
        <div className="page-header">
          <h1>Productos</h1>
        </div>

        {showForm ? (
          <ProductForm
            product={editingProduct}
            handleCreateProductApi={handleCreateProductApi}
            onCancel={handleCancel}
          />
        ) : (
          <>
            <div className="card mb-3">
              <div className="card-body">
                <div className="productos-search-toolbar d-flex align-items-center flex-wrap">
                  <div className="productos-search__wrapper">
                    <input
                      type="text"
                      className="form-control productos-search__input productos-search__input--with-btn"
                      placeholder="Buscar por nombre o código..."
                      value={searchTerm}
                      onChange={(e) => setSearchTerm(e.target.value)}
                      onKeyDown={(e) => e.key === "Enter" && handleSearchSubmit()}
                    />
                    {searchTerm && (
                      <button
                        className="btn productos-search__clear"
                        type="button"
                        title="Limpiar búsqueda"
                        onClick={handleClearSearch}
                        disabled={searchLoading}
                      >
                        <i className="fas fa-times" />
                      </button>
                    )}
                    <button
                      className="productos-search__go"
                      type="button"
                      title="Buscar"
                      onClick={handleSearchSubmit}
                      disabled={searchLoading || !searchTerm.trim()}
                    >
                      {searchLoading ? (
                        <span className="spinner-border spinner-border-sm" role="status" aria-hidden="true" />
                      ) : (
                        <i className="fas fa-search" />
                      )}
                    </button>
                  </div>
                  <div className="productos-search__model">
                    <button
                      type="button"
                      className={`productos-search__model-btn ${
                        appliedModelFilter ? "productos-search__model-btn--active" : ""
                      }`}
                      onClick={() => setShowModelFilter((v) => !v)}
                    >
                      <i className="fas fa-car mr-1" />
                      {appliedModelFilter
                        ? `Modelo: ${models.find((m) => m.id === appliedModelFilter)?.name || `ID ${appliedModelFilter}`}`
                        : "Modelo"}
                      <i className={`fas fa-chevron-down ml-2 productos-search__model-chevron ${showModelFilter ? "productos-search__model-chevron--open" : ""}`} />
                    </button>
                    {showModelFilter && (
                      <div className="productos-search__model-panel">
                        <label className="productos-search__model-label">Filtrar por modelo</label>
                        <select
                          className="form-control productos-search__model-select"
                          value={appliedModelFilter ?? ""}
                          onChange={(e) => {
                            const val = e.target.value;
                            const next = val ? Number(val) : null;
                            setAppliedModelFilter(next);
                            setPage(1);
                            clearSelection();
                            setShowModelFilter(false);
                          }}
                        >
                          <option value="">Todos los modelos</option>
                          {models.map((m) => (
                            <option key={m.id} value={m.id}>
                              {m.name}
                            </option>
                          ))}
                        </select>
                      </div>
                    )}
                  </div>
                  <FilterDropdown
                    icon="fas fa-toggle-on"
                    title={
                      urlStatus === 1
                        ? "Estado · Activos"
                        : urlStatus === 0
                        ? "Estado · Inactivos"
                        : "Estado"
                    }
                    active={urlStatus !== undefined}
                    open={showStatusFilter}
                    onToggle={() => setShowStatusFilter((v) => !v)}
                    onClose={() => setShowStatusFilter(false)}
                    selectLabel="Filtrar por estado"
                    value={urlStatus !== undefined ? String(urlStatus) : ""}
                    options={[
                      { value: "", label: "Todos los estados" },
                      { value: "1", label: "Activos" },
                      { value: "0", label: "Inactivos" },
                    ]}
                    onChange={(value) => {
                      setPage(1);
                      clearSelection();
                      pushQuery({ status: value || undefined });
                    }}
                  />
                  <FilterDropdown
                    icon="fas fa-images"
                    title={
                      urlFilter === "con_imagen"
                        ? "Imágenes · Con imagen"
                        : urlFilter === "sin_imagen"
                        ? "Imágenes · Sin imagen"
                        : "Imágenes"
                    }
                    active={urlFilter === "con_imagen" || urlFilter === "sin_imagen"}
                    open={showImageFilter}
                    onToggle={() => setShowImageFilter((v) => !v)}
                    onClose={() => setShowImageFilter(false)}
                    selectLabel="Filtrar por imágenes"
                    value={urlFilter === "con_imagen" || urlFilter === "sin_imagen" ? urlFilter : ""}
                    options={[
                      { value: "", label: "Todos" },
                      { value: "con_imagen", label: "Con imagen" },
                      { value: "sin_imagen", label: "Sin imagen" },
                    ]}
                    onChange={(value) => {
                      setPage(1);
                      clearSelection();
                      pushQuery({ filter: value || undefined });
                    }}
                  />
                  <FilterDropdown
                    icon="fas fa-clipboard-check"
                    title={
                      urlFilter === "sin_categoria"
                        ? "Datos · Sin categoría"
                        : urlFilter === "sin_reference"
                        ? "Datos · Sin N° de piezas"
                        : urlFilter === "incompletos"
                        ? "Datos · Incompletos"
                        : "Datos"
                    }
                    active={
                      urlFilter === "sin_categoria"
                      || urlFilter === "sin_reference"
                      || urlFilter === "incompletos"
                    }
                    open={showDataFilter}
                    onToggle={() => setShowDataFilter((v) => !v)}
                    onClose={() => setShowDataFilter(false)}
                    selectLabel="Filtrar por campos faltantes"
                    value={
                      urlFilter === "sin_categoria"
                      || urlFilter === "sin_reference"
                      || urlFilter === "incompletos"
                        ? urlFilter
                        : ""
                    }
                    options={[
                      { value: "", label: "Todos" },
                      { value: "sin_categoria", label: "Sin categoría" },
                      { value: "sin_reference", label: "Sin número de piezas (0)" },
                      { value: "incompletos", label: "Incompletos (falta cualquier campo)" },
                    ]}
                    onChange={(value) => {
                      setPage(1);
                      clearSelection();
                      pushQuery({ filter: value || undefined });
                    }}
                  />
                  <button
                    type="button"
                    className="btn btn-outline-danger productos-search__action"
                    onClick={() => (allProductsSelected ? handleDeleteAll() : handleDeleteSelected())}
                    disabled={!hasPartialSelection}
                  >
                    <i className="fas fa-trash-alt mr-1" />
                    {allProductsSelected
                      ? "Eliminar todos"
                      : `Eliminar${hasPartialSelection ? ` (${selectedCount})` : ""}`}
                  </button>
                  <button
                    type="button"
                    className="productos-search__new"
                    onClick={handleCreate}
                  >
                    <i className="fas fa-plus mr-1" />
                    Nuevo producto
                  </button>
                </div>
                {searchTerm && !searchLoading && (
                  <small className="text-muted mt-2 d-block">
                    {products.length} producto{products.length !== 1 ? "s" : ""} encontrado
                    {products.length !== 1 ? "s" : ""}
                  </small>
                )}
                {appliedModelFilter && (
                  <small className="text-primary mt-1 d-block">
                    Filtro activo por modelo:{" "}
                    {models.find((m) => m.id === appliedModelFilter)?.name || `ID ${appliedModelFilter}`}
                  </small>
                )}
              </div>
            </div>
            <div className="position-relative">
              {searchLoading && (
                <div
                  className="position-absolute d-flex align-items-center justify-content-center"
                  style={{
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    backgroundColor: "rgba(255,255,255,0.85)",
                    zIndex: 10,
                    minHeight: 200,
                  }}
                >
                  <div className="text-center">
                    <div className="spinner-border text-primary mb-2" role="status">
                      <span className="sr-only">Cargando...</span>
                    </div>
                    <p className="text-muted mb-0">Cargando resultados...</p>
                  </div>
                </div>
              )}
              <ProductList
                products={products}
                onEdit={handleEdit}
                onDelete={handleDelete}
                isProductSelected={isProductSelected}
                onToggleProduct={handleToggleProduct}
                onToggleAllVisible={handleToggleAllVisible}
              />
            </div>
            {totalPages > 1 && !searchTerm && (
              <div className="pagination-container mt-4">
                <button
                  className="btn btn-sm btn-secondary"
                  disabled={page === 1}
                  onClick={() => setPage(page - 1)}
                >
                  Anterior
                </button>
                <span className="mx-3">
                  Página {page} de {totalPages}
                </span>
                <button
                  className="btn btn-sm btn-secondary"
                  disabled={page >= totalPages}
                  onClick={() => setPage(page + 1)}
                >
                  Siguiente
                </button>
              </div>
            )}
          </>
        )}
      </AdminLayout>
    </ProtectedRoute>
  );
}

export default ProductosPage;
