﻿// react
import React, { useState, useEffect } from "react";
// application
import AdminLayout from "~/admin/components/AdminLayout";
import ProtectedRoute from "~/admin/components/ProtectedRoute";
import OfferForm from "~/admin/components/offers/OfferForm";
import OfferList from "~/admin/components/offers/OfferList";
import { IOffer } from "~/admin/interfaces/offer";
import { productsApi } from "~/admin/services/productsApi";
import { IProduct } from "~/admin/interfaces/product";
import { toast } from "react-toastify";
import { offersApi } from "~/admin/services/offersApi";

function OfertasPage() {
  const [offers, setOffers] = useState<IOffer[]>([]);
  const [allOffers, setAllOffers] = useState<IOffer[]>([]);
  const [products, setProducts] = useState<IProduct[]>([]);
  const [editingOffer, setEditingOffer] = useState<IOffer | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [loading, setLoading] = useState(true);
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedOfferIds, setSelectedOfferIds] = useState<number[]>([]);

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

  const loadOffers = async () => {
    try {
      setLoading(true);
      const response = await offersApi.getAll();
      setAllOffers(response.data);
      setOffers(response.data);

      const productsData = response.data.map(
        (offer) =>
          ({
            id: offer.id,
            name: offer.name || "",
            code: "",
            price: 0,
            stock: "in-stock",
            discount: offer.discount || 0,
          } as IProduct)
      );
      setProducts(productsData);
    } catch (error: any) {
      toast.error(error.message || "Error al cargar ofertas");
    } finally {
      setLoading(false);
    }
  };

  const handleSearch = (term: string) => {
    setSearchTerm(term);
    
    if (!term.trim()) {
      setOffers(allOffers);
      return;
    }

    // Búsqueda instantánea en las ofertas ya cargadas
    const filtered = allOffers.filter((offer) => {
      const searchLower = term.toLowerCase().trim();
      const idMatch = offer.id?.toString().includes(searchLower) || false;
      const nameMatch = offer.name?.toLowerCase().includes(searchLower) || false;
      const discountMatch = offer.discount?.toString().includes(searchLower) || false;
      
      return idMatch || nameMatch || discountMatch;
    });

    setOffers(filtered);
  };

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

  const handleEdit = (offer: IOffer) => {
    setEditingOffer(offer);
    setShowForm(true);
  };

  const handleSave = async (offer: IOffer) => {
    try {
            if (editingOffer?.id) {
        await productsApi.updateOffer(
          editingOffer.id,
          offer.discount,
          offer.startDate,
          offer.endDate
        );
        toast.success("Oferta actualizada exitosamente");
      } else if (offer.type === "all") {
        if (!offer.discount || offer.discount <= 0) {
          toast.error("El porcentaje de descuento debe ser mayor a 0");
          return;
        }

        const confirmMsg = `¿Aplicar ${offer.discount}% de descuento a TODOS los productos? Esto actualizará el campo discount de cada producto en la base de datos.`;
        if (!confirm(confirmMsg)) return;

        const result = await offersApi.bulkDiscount(offer.discount);
        toast.success(
          result.affectedRows > 0
            ? `Descuento del ${result.discount}% aplicado a ${result.affectedRows} producto${result.affectedRows !== 1 ? "s" : ""}`
            : "Descuento aplicado a todos los productos"
        );
      } else {
        if (!offer.productIds || offer.productIds.length === 0) {
          toast.error("Debes seleccionar al menos un producto");
          return;
        }
        if (!offer.startDate || !offer.endDate) {
          toast.error("Debes asignar la vigencia (fecha desde / hasta)");
          return;
        }

        const result = await offersApi.bulkApply(
          offer.productIds,
          offer.discount,
          offer.startDate,
          offer.endDate
        );
                toast.success(
          `Oferta del ${result.discount}% aplicada a ${result.affectedRows} producto(s). Vigencia: ${result.startDate} al ${result.endDate}`
        );
      }
      setShowForm(false);
      setEditingOffer(null);
      loadOffers();
    } catch (error: any) {
      toast.error(error.message || "Error al guardar oferta");
    }
  };

  const handleDelete = async (id: number) => {
    if (
      !confirm(
        "¿Estás seguro de eliminar esta oferta? (El producto se convertirá en normal)"
      )
    ) {
      return;
    }

    try {
      await productsApi.updateOffer(id, 0);
      toast.success("Oferta eliminada exitosamente");
      setSelectedOfferIds((prev) => prev.filter((x) => x !== id));
      loadOffers();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar oferta");
    }
  };

  const handleDeleteSelected = async () => {
    if (selectedOfferIds.length === 0) return;
    const msg = `¿Eliminar ${selectedOfferIds.length} oferta${selectedOfferIds.length !== 1 ? "s" : ""} seleccionada${selectedOfferIds.length !== 1 ? "s" : ""}? (Los productos se convertirán en normales)`;
    if (!confirm(msg)) return;

    try {
      await Promise.all(
        selectedOfferIds.map((id) => productsApi.updateOffer(id, 0))
      );
      toast.success("Ofertas seleccionadas eliminadas");
      setSelectedOfferIds([]);
      loadOffers();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar ofertas seleccionadas");
    }
  };

  const handleDeleteAll = async () => {
    if (
      !confirm(
        "¿Eliminar TODAS las ofertas? Todos los productos con descuento volverán a ser normales."
      )
    ) {
      return;
    }

    try {
      const affected = await offersApi.deleteAll();
      toast.success(
        affected > 0
          ? `Se eliminaron ${affected} oferta${affected !== 1 ? "s" : ""}`
          : "No había ofertas activas"
      );
      setSelectedOfferIds([]);
      loadOffers();
    } catch (error: any) {
      toast.error(error.message || "Error al eliminar todas las ofertas");
    }
  };

  const handleToggleOffer = (id: number, checked: boolean) => {
    setSelectedOfferIds((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) {
      setSelectedOfferIds([]);
      return;
    }

    if (searchTerm.trim()) {
      setSelectedOfferIds(Array.from(new Set(ids)));
      return;
    }

    const allIds = allOffers
      .map((o) => o.id)
      .filter((id): id is number => typeof id === "number");
    setSelectedOfferIds(Array.from(new Set(allIds)));
  };

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

  const allOfferIds = allOffers
    .map((o) => o.id)
    .filter((id): id is number => typeof id === "number");
  const allOffersSelected =
    allOfferIds.length > 0 &&
    allOfferIds.length === selectedOfferIds.length &&
    allOfferIds.every((id) => selectedOfferIds.includes(id));
  const hasPartialSelection =
    selectedOfferIds.length > 0 && !allOffersSelected;

  if (loading && offers.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>Ofertas</h1>
          {!showForm && (
            <div>
              <button
                className="btn btn-danger mr-2"
                onClick={handleDeleteAll}
                disabled={!allOffersSelected}
              >
                <i className="fas fa-trash-alt" /> Eliminar todas
              </button>
              <button
                className="btn btn-danger mr-2"
                onClick={handleDeleteSelected}
                disabled={!hasPartialSelection}
              >
                <i className="fas fa-trash" /> Eliminar seleccionadas
                {hasPartialSelection ? ` (${selectedOfferIds.length})` : ""}
              </button>
              <button className="btn btn-primary" onClick={handleCreate}>
                <i className="fas fa-plus" /> Nueva Oferta
              </button>
            </div>
          )}
        </div>

        {showForm ? (
          <OfferForm
            offer={editingOffer}
            products={products}
            onSave={handleSave}
            onCancel={handleCancel}
          />
        ) : (
          <>
            <div className="card mb-3">
              <div className="card-body">
                <div className="input-group">
                  <div className="input-group-prepend">
                    <span className="input-group-text">
                      <i className="fas fa-search" />
                    </span>
                  </div>
                  <input
                    type="text"
                    className="form-control"
                    placeholder="Buscar por ID, nombre o descuento..."
                    value={searchTerm}
                    onChange={(e) => handleSearch(e.target.value)}
                  />
                  {searchTerm && (
                    <div className="input-group-append">
                      <button
                        className="btn btn-outline-secondary"
                        type="button"
                        onClick={() => handleSearch("")}
                      >
                        <i className="fas fa-times" />
                      </button>
                    </div>
                  )}
                </div>
                {searchTerm && (
                  <small className="text-muted mt-2 d-block">
                    {offers.length} oferta{offers.length !== 1 ? 's' : ''} encontrada{offers.length !== 1 ? 's' : ''}
                  </small>
                )}
              </div>
            </div>
            <OfferList
              offers={offers}
              onEdit={handleEdit}
              onDelete={handleDelete}
              selectedOfferIds={selectedOfferIds}
              onToggleOffer={handleToggleOffer}
              onToggleAllVisible={handleToggleAllVisible}
            />
          </>
        )}
      </AdminLayout>
    </ProtectedRoute>
  );
}

export default OfertasPage;
