﻿// react
import React, { useState, useEffect, useMemo } from "react";
// third-party
import { useForm } from "react-hook-form";
// application
import { IOffer } from "~/admin/interfaces/offer";
import { IProduct } from "~/admin/interfaces/product";
import { IBrand, IModel } from "~/admin/interfaces/vehicle";
import { productsApi } from "~/admin/services/productsApi";
import { vehiclesApi } from "~/admin/services/vehiclesApi";
import { toast } from "react-toastify";

interface Props {
  offer?: IOffer | null;
  products: IProduct[];
  onSave: (offer: IOffer) => void;
  onCancel: () => void;
}

function OfferForm({ offer, products, onSave, onCancel }: Props) {
  const isEditMode = Boolean(offer?.id);
  const [selectedProducts, setSelectedProducts] = useState<number[]>(
    offer?.id ? [offer.id] : offer?.productIds || []
  );
  const [offerType, setOfferType] = useState<"all" | "selected">(
    offer?.id ? "selected" : offer?.type || "selected"
  );
    const [allProducts, setAllProducts] = useState<IProduct[]>([]);
  const [loadingProducts, setLoadingProducts] = useState(false);
  const [productSearch, setProductSearch] = useState("");
  // Filtros por marca y modelo
  const [brands, setBrands] = useState<IBrand[]>([]);
  const [models, setModels] = useState<IModel[]>([]);
  const [filterBrand, setFilterBrand] = useState<number | null>(null);
  const [filterModel, setFilterModel] = useState<number | null>(null);
  // Vigencia de la oferta
  const [startDate, setStartDate] = useState(offer?.startDate || "");
  const [endDate, setEndDate] = useState(offer?.endDate || "");

  useEffect(() => {
    vehiclesApi.getAllBrands().then(setBrands).catch(() => {});
    vehiclesApi.getAllModels(true).then(setModels).catch(() => {});
  }, []);

  useEffect(() => {
    if (isEditMode) {
      setLoadingProducts(false);
      return;
    }

    loadAllProducts();
  }, [isEditMode]);

  useEffect(() => {
    if (offer?.id) {
      setSelectedProducts([offer.id]);
      setOfferType("selected");
      setProductSearch("");
      return;
    }

    setSelectedProducts(offer?.productIds || []);
    setOfferType(offer?.type || "selected");
  }, [offer]);

  const loadAllProducts = async () => {
    try {
      setLoadingProducts(true);
      // Primero obtenemos la primera página para saber cuántos productos hay en total
      const firstPage = await productsApi.getAll(1, 20);
      const totalItems =
        firstPage.pagination?.total_items || firstPage.count || 0;
      const limit = firstPage.pagination?.limit || 20;
      const totalPages =
        firstPage.pagination?.total_pages || Math.ceil(totalItems / limit);

      let allProductsData = [...firstPage.data];

      // Si hay más páginas, obtenemos todas las demás
      if (totalPages > 1) {
        const remainingPages = [];
        for (let page = 2; page <= totalPages; page++) {
          remainingPages.push(productsApi.getAll(page, limit));
        }

        const remainingResponses = await Promise.all(remainingPages);
        remainingResponses.forEach((response) => {
          allProductsData = [...allProductsData, ...response.data];
        });
      }

      setAllProducts(allProductsData);
    } catch (error) {
      console.error("Error loading products:", error);
      toast.error("Error al cargar productos");
    } finally {
      setLoadingProducts(false);
    }
  };

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<IOffer>({
    defaultValues: offer || {
      name: "",
      discount: 0,
      type: "selected",
      startDate: "",
      endDate: "",
      active: true,
    },
  });

  const onSubmit = async (data: IOffer) => {
    try {
      if (offerType === "selected" && selectedProducts.length === 0) {
        toast.error("Debes seleccionar al menos un producto");
        return;
      }
      if (!startDate || !endDate) {
        toast.error("Debes asignar la vigencia (fecha desde / hasta)");
        return;
      }
      if (endDate < startDate) {
        toast.error("La fecha final no puede ser menor a la inicial");
        return;
      }

      onSave({
        ...data,
        id: offer?.id,
        type: offerType,
        productIds: offerType === "selected" ? selectedProducts : undefined,
        startDate,
        endDate,
      });
    } catch (error: any) {
      toast.error(error.message || "Error al guardar oferta");
    }
  };

  const handleProductToggle = (productId: number) => {
    if (isEditMode) return;

    if (selectedProducts.includes(productId)) {
      setSelectedProducts(selectedProducts.filter((id) => id !== productId));
    } else {
      setSelectedProducts([...selectedProducts, productId]);
    }
  };

  const filteredProducts = useMemo(() => {
    if (isEditMode) {
      if (!offer?.id) return [];
      const offerProduct = products.find((product) => product.id === offer.id);
      if (offerProduct) return [offerProduct];
      return [
        {
          id: offer.id,
          name: offer.name || "",
          code: "",
          price: 0,
          stock: "in-stock",
        } as IProduct,
      ];
    }

    const q = productSearch.toLowerCase();
    return allProducts.filter((product) => {
      // Filtro por marca (vehicle_brandID) y modelo (vehicleId = vehicle_modelID)
      if (filterBrand && product.vehicle_brandID !== filterBrand) return false;
      if (filterModel && product.vehicleId !== filterModel) return false;
      if (!productSearch.trim()) return true;
      return (
        product.name?.toLowerCase().includes(q) ||
        product.code?.toLowerCase().includes(q) ||
        String(product.price ?? "").toLowerCase().includes(q)
      );
    });
  }, [allProducts, productSearch, isEditMode, offer, products, filterBrand, filterModel]);

  const availableModels = filterBrand
    ? models.filter((m) => m.vehicle_brandID === filterBrand)
    : models;

  return (
    <div className="card">
      <div className="card-header">
        <h3>{offer ? "Editar Oferta" : "Nueva Oferta"}</h3>
      </div>
      <div className="card-body">
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="form-group">
            <label>Porcentaje de Descuento *</label>
            <div className="input-group">
              <input
                type="number"
                min="0"
                max="100"
                className={`form-control ${
                  errors.discount ? "is-invalid" : ""
                }`}
                {...register("discount", {
                  required: "El descuento es requerido",
                  min: { value: 1, message: "El descuento debe ser mayor a 0" },
                  max: {
                    value: 100,
                    message: "El descuento no puede ser mayor a 100%",
                  },
                  valueAsNumber: true,
                })}
              />
              <div className="input-group-append">
                <span className="input-group-text">%</span>
              </div>
            </div>
            {errors.discount && (
              <div className="invalid-feedback">{errors.discount.message}</div>
            )}
          </div>

          <div className="form-group">
            <label>Tipo de Oferta *</label>
            <select
              className="form-control"
              value={offerType}
              disabled={isEditMode}
              onChange={(e) =>
                setOfferType(e.target.value as "all" | "selected")
              }
            >
              <option value="selected">Productos seleccionados</option>
              <option value="all">Todos los productos</option>
            </select>
            {offerType === "all" && !isEditMode && (
              <small className="text-muted d-block mt-2">
                Al guardar, se aplicará el porcentaje de descuento a todos los
                productos mediante{" "}
                <code>UPDATE productos SET discount = valor</code>.
              </small>
            )}
          </div>

                    <div className="form-group">
            <label>Vigencia de la Oferta *</label>
            <div className="row">
              <div className="col-md-6">
                <label>Desde</label>
                <input
                  type="date"
                  className={`form-control ${startDate && endDate && endDate < startDate ? "is-invalid" : ""}`}
                  value={startDate}
                  onChange={(e) => setStartDate(e.target.value)}
                  required
                />
              </div>
              <div className="col-md-6">
                <label>Hasta</label>
                <input
                  type="date"
                  className={`form-control ${
                    startDate && endDate && endDate < startDate ? "is-invalid" : ""
                  }`}
                  value={endDate}
                  onChange={(e) => setEndDate(e.target.value)}
                  required
                />
              </div>
            </div>
            {startDate && endDate && endDate < startDate ? (
              <div className="invalid-feedback d-block">
                La fecha final no puede ser menor a la inicial
              </div>
            ) : (
              <small className="text-muted d-block mt-1">
                El descuento estarÃ¡ activo automÃ¡ticamente en ese rango. Al llegar la
                fecha final, la oferta se cancela y el producto vuelve a su precio full.
              </small>
            )}
          </div>

          {offerType === "selected" && (
            <div className="form-group">
              {!isEditMode && (
                <>
                  <div className="row">
                    <div className="col-md-6">
                      <label>Marca</label>
                      <select
                        className="form-control"
                        value={filterBrand ?? ""}
                        disabled={loadingProducts}
                        onChange={(e) => {
                          setFilterBrand(e.target.value ? Number(e.target.value) : null);
                          setFilterModel(null);
                        }}
                      >
                        <option value="">Todas las marcas</option>
                        {brands.map((b) => (
                          <option key={b.id} value={b.id}>
                            {b.name}
                          </option>
                        ))}
                      </select>
                    </div>
                    <div className="col-md-6">
                      <label>Modelo</label>
                      <select
                        className="form-control"
                        value={filterModel ?? ""}
                        disabled={loadingProducts || !filterBrand}
                        onChange={(e) =>
                          setFilterModel(e.target.value ? Number(e.target.value) : null)
                        }
                      >
                        <option value="">
                          {filterBrand ? "Todos los modelos" : "Elige una marca primero"}
                        </option>
                        {availableModels.map((m) => (
                          <option key={m.id} value={m.id}>
                            {m.name}
                          </option>
                        ))}
                      </select>
                    </div>
                                    </div>
                  <input
                    type="text"
                    className="form-control mb-2 mt-2"
                    placeholder="Buscar"
                    value={productSearch}
                    onChange={(e) => setProductSearch(e.target.value)}
                    disabled={loadingProducts}
                  />
                </>
              )}
              <label>
                {isEditMode ? "Producto Seleccionado *" : "Seleccionar Productos *"}
              </label>
              {loadingProducts ? (
                <div className="text-center py-3">
                  <div
                    className="spinner-border spinner-border-sm"
                    role="status"
                  >
                    <span className="sr-only">Cargando productos...</span>
                  </div>
                  <small className="d-block mt-2 text-muted">
                    Cargando productos...
                  </small>
                </div>
              ) : (
                <>
                  {(() => {
                    const availableCount = isEditMode
                      ? filteredProducts.length
                      : allProducts.length;
                    return (
                  <div
                    className="product-selector"
                    style={{ maxHeight: "300px", overflowY: "auto" }}
                  >
                    {availableCount === 0 ? (
                      <p className="text-muted">No hay productos disponibles</p>
                    ) : filteredProducts.length === 0 ? (
                      <p className="text-muted">
                        Ningún producto coincide con &quot;{productSearch}&quot;
                      </p>
                    ) : (
                      filteredProducts.map((product) => (
                        <div key={product.id} className="form-check">
                          <input
                            className="form-check-input"
                            type="checkbox"
                            checked={selectedProducts.includes(product.id!)}
                            disabled={isEditMode}
                            onChange={() => handleProductToggle(product.id!)}
                          />
                          <label className="form-check-label">
                            {product.name}
                          </label>
                        </div>
                      ))
                    )}
                  </div>
                    );
                  })()}
                  {(isEditMode ? filteredProducts.length : allProducts.length) > 0 && (
                    <small className="text-muted d-block mt-2">
                      {isEditMode
                        ? "1 producto asignado a esta oferta"
                        : productSearch.trim()
                        ? `${filteredProducts.length} de ${allProducts.length} producto(s)`
                        : `${allProducts.length} producto(s) disponible(s)`}
                    </small>
                  )}
                  {selectedProducts.length === 0 && (
                    <small className="text-danger d-block mt-2">
                      Debes seleccionar al menos un producto
                    </small>
                  )}
                </>
              )}
            </div>
          )}

          <div className="form-actions">
            <button
              type="submit"
              className="btn btn-primary"
              disabled={
                offerType === "selected" && selectedProducts.length === 0
              }
            >
              <i className="fas fa-save" /> Guardar
            </button>
            <button
              type="button"
              className="btn btn-secondary ml-2"
              onClick={onCancel}
            >
              Cancelar
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default OfferForm;
