import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Row, Col, Card, Form, Button, Spinner } from 'react-bootstrap';
import { router } from '@inertiajs/react';
import Swal from 'sweetalert2';
import { Eraser, FilterX } from 'lucide-react';
import { useLoading } from '../../../LoadingContext';
import useInfinitePuntos from './hooks/useInfinitePuntos';
import { PuntoSuministro } from '../Contratos/Interfaces/Interfaces';
import PuntoCard from './PuntoCard';
import { Typeahead } from 'react-bootstrap-typeahead';
import 'react-bootstrap-typeahead/css/Typeahead.css';
import { getProvincias, getLocalidades, getCupsElectricos, getCupsGas } from '../../../services/dataService';
import estilosFoco from '../Contratos/Shared/estilosFocoAccesible.module.css';
import styles from './PuntoCardsView.module.css';

interface Props {
  initialPuntos: PuntoSuministro[];
  initialPagination: {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
    from?: number;
    to?: number;
  };
}

const FILTROS_INICIALES = {
  RazSocCli: '',
  NumCifCli: '',
  NomViaPunSum: '',
  CodLoc: '',
  CodPro: '',
  Cups: '',
  TipoCups: 'electrico',
};

const PuntoCardsView: React.FC<Props> = ({ initialPuntos, initialPagination }) => {
  const { showLoading, hideLoading } = useLoading();
  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const [filters, setFilters] = useState(FILTROS_INICIALES);

  // Estados para catálogos de base de datos
  const [provincias, setProvincias] = useState<any[]>([]);
  const [localidades, setLocalidades] = useState<any[]>([]);
  const [cupsElectricos, setCupsElectricos] = useState<any[]>([]);
  const [cupsGas, setCupsGas] = useState<any[]>([]);
  const [isCargandoCatalogos, setIsCargandoCatalogos] = useState(false);

  // Estados de selección para Typeaheads
  const [selectedProvincia, setSelectedProvincia] = useState<any[]>([]);
  const [selectedLocalidad, setSelectedLocalidad] = useState<any[]>([]);
  const [selectedCups, setSelectedCups] = useState<any[]>([]);

  // Cargar catálogos al montar
  useEffect(() => {
    setIsCargandoCatalogos(true);
    Promise.all([
      getProvincias().then(res => setProvincias(res.data || [])).catch(() => {}),
      getLocalidades().then(res => setLocalidades(res.data || [])).catch(() => {}),
      getCupsElectricos().then(res => setCupsElectricos(res.data || [])).catch(() => {}),
      getCupsGas().then(res => setCupsGas(res.data || [])).catch(() => {}),
    ]).finally(() => setIsCargandoCatalogos(false));
  }, []);

  const { puntos, pagination, isLoading, hasMore, resetWithFilters, sentinelRef } = useInfinitePuntos({
    initialPuntos,
    initialPagination,
    filters,
  });

  const debouncedResetFilters = useCallback(
    (newFilters: Record<string, string>) => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }

      debounceTimerRef.current = setTimeout(() => {
        resetWithFilters(newFilters);
      }, 500);
    },
    [resetWithFilters],
  );

  useEffect(() => {
    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
    };
  }, []);

  const updateFilter = useCallback(
    (key: keyof typeof FILTROS_INICIALES, value: string) => {
      const newFilters = { ...filters, [key]: value };
      setFilters(newFilters);
      debouncedResetFilters(newFilters);
    },
    [filters, debouncedResetFilters],
  );

  const limpiarFiltros = useCallback(() => {
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
    }
    setFilters(FILTROS_INICIALES);
    setSelectedProvincia([]);
    setSelectedLocalidad([]);
    setSelectedCups([]);
    resetWithFilters(FILTROS_INICIALES);
  }, [resetWithFilters]);

  const hayFiltrosActivos = Object.entries(filters).some(([key, value]) => {
    if (key === 'TipoCups') return false;
    if (typeof value === 'number') {
      return value > 0;
    }
    if (typeof value === 'string') {
      return value.trim() !== '';
    }
    return !!value;
  });

  const handleView = (punto: PuntoSuministro) => {
    try {
      showLoading();
      router.visit(route('puntos-suministro.ver', { id: punto.CodPunSum }), {
        onFinish: () => hideLoading(),
        onError: () => hideLoading(),
      });
    } catch {
      hideLoading();
    }
  };

  const handleEdit = (punto: PuntoSuministro) => {
    try {
      showLoading();
      router.visit(route('puntos-suministro.edit', { id: punto.CodPunSum }), {
        onFinish: () => hideLoading(),
        onError: () => hideLoading(),
      });
    } catch {
      hideLoading();
    }
  };

  const handleDelete = async (punto: PuntoSuministro) => {
    try {
      const direccion = [punto.NomViaPunSum, punto.NumViaPunSum].filter(Boolean).join(' ');
      const result = await Swal.fire({
        title: '¿Estás seguro?',
        text: `¿Deseas eliminar el punto ${direccion || punto.CodPunSum}? Esta acción no se puede deshacer.`,
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#3085d6',
        confirmButtonText: 'Sí, eliminar',
        cancelButtonText: 'Cancelar',
      });

      if (result.isConfirmed) {
        showLoading();
        router.delete(route('puntos-suministro.destroy', { id: punto.CodPunSum }), {
          preserveScroll: true,
          onSuccess: () => {
            hideLoading();
            Swal.fire({
              title: 'Eliminado',
              text: 'El punto ha sido eliminado correctamente',
              icon: 'success',
              timer: 2000,
              showConfirmButton: false,
            });
            resetWithFilters(filters);
          },
          onError: () => {
            hideLoading();
            Swal.fire({
              title: 'Error',
              text: 'Error al eliminar el punto',
              icon: 'error',
              timer: 3000,
              showConfirmButton: false,
            });
          },
        });
      }
    } catch (deleteError) {
      hideLoading();
      console.error('Error en handleDelete:', deleteError);
    }
  };

  return (
    <div className={`${styles.contenedorVista} ${estilosFoco.contenedorAccesibleContratos}`}>
      <Card className={`mb-3 ${styles.filtrosCard}`}>
        <Card.Body>
          <div className={styles.cabeceraFiltros}>
            <Form.Group className="mb-0">
              <Form.Label className={`${styles.tituloFiltros} d-flex flex-wrap align-items-center gap-2 mb-0`}>
                <span>Filtros</span>
                <span className={styles.contadorResultados} aria-live="polite">
                  Mostrando {puntos.length} de {pagination.total.toLocaleString('es-ES')} puntos
                </span>
                {isLoading && (
                  <Spinner
                    animation="border"
                    size="sm"
                    variant="primary"
                    className="ms-1 align-middle"
                    style={{ width: '1rem', height: '1rem', borderWidth: '0.15em' }}
                    role="status"
                    aria-hidden="true"
                  />
                )}
              </Form.Label>
            </Form.Group>
            {hayFiltrosActivos && (
              <Button
                type="button"
                variant="outline-secondary"
                size="sm"
                onClick={limpiarFiltros}
                disabled={isLoading}
                aria-label="Limpiar filtros de búsqueda"
              >
                <FilterX size={16} className="me-1" aria-hidden="true" />
                Limpiar filtros
              </Button>
            )}
          </div>

          <Row className="g-2 mt-2">
            <Col xs={12} sm={6} lg={3}>
              <Form.Group controlId="filtro-razon-social">
                <Form.Label className="small mb-1">Razón social</Form.Label>
                <Form.Control
                  size="sm"
                  placeholder="Buscar por razón social"
                  value={filters.RazSocCli}
                  onChange={(e) => updateFilter('RazSocCli', e.target.value)}
                />
              </Form.Group>
            </Col>
            <Col xs={12} sm={6} lg={2}>
              <Form.Group controlId="filtro-nif">
                <Form.Label className="small mb-1">NIF</Form.Label>
                <Form.Control
                  size="sm"
                  placeholder="Buscar por NIF"
                  value={filters.NumCifCli}
                  onChange={(e) => updateFilter('NumCifCli', e.target.value)}
                />
              </Form.Group>
            </Col>
            <Col xs={12} sm={6} lg={3}>
              <Form.Group controlId="filtro-direccion">
                <Form.Label className="small mb-1">Dirección</Form.Label>
                <Form.Control
                  size="sm"
                  placeholder="Buscar por dirección"
                  value={filters.NomViaPunSum}
                  onChange={(e) => updateFilter('NomViaPunSum', e.target.value)}
                />
              </Form.Group>
            </Col>
            <Col xs={12} sm={6} lg={2}>
              <Form.Group controlId="filtro-provincia">
                <Form.Label className="small mb-1">Provincia</Form.Label>
                <div className={styles.grupoTypeaheadConLimpiar}>
                  <Typeahead
                    id="typeahead-provincia"
                    labelKey="DesPro"
                    placeholder="Provincia..."
                    size="sm"
                    options={provincias}
                    selected={selectedProvincia}
                    onChange={(selected: any[]) => {
                      setSelectedProvincia(selected);
                      setSelectedLocalidad([]);
                      updateFilter('CodPro', selected[0]?.CodPro || '');
                      updateFilter('CodLoc', '');
                    }}
                    isLoading={isCargandoCatalogos}
                    emptyLabel="No se encontraron provincias"
                  />
                  {selectedProvincia.length > 0 && (
                    <button
                      type="button"
                      className={styles.botonLimpiarTypeahead}
                      onClick={() => {
                        setSelectedProvincia([]);
                        setSelectedLocalidad([]);
                        updateFilter('CodPro', '');
                        updateFilter('CodLoc', '');
                      }}
                      onMouseDown={(e) => e.preventDefault()}
                      title="Limpiar provincia"
                      aria-label="Limpiar provincia"
                    >
                      <Eraser size={14} aria-hidden />
                    </button>
                  )}
                </div>
              </Form.Group>
            </Col>
            <Col xs={12} sm={6} lg={2}>
              <Form.Group controlId="filtro-localidad">
                <Form.Label className="small mb-1">Localidad</Form.Label>
                <div className={styles.grupoTypeaheadConLimpiar}>
                  <Typeahead
                    id="typeahead-localidad"
                    labelKey="DesLoc"
                    placeholder="Localidad..."
                    size="sm"
                    options={selectedProvincia.length > 0 
                      ? localidades.filter(loc => loc.CodPro === selectedProvincia[0].CodPro)
                      : localidades
                    }
                    selected={selectedLocalidad}
                    onChange={(selected: any[]) => {
                      setSelectedLocalidad(selected);
                      updateFilter('CodLoc', selected[0]?.CodLoc || '');
                    }}
                    isLoading={isCargandoCatalogos}
                    emptyLabel="No se encontraron localidades"
                  />
                  {selectedLocalidad.length > 0 && (
                    <button
                      type="button"
                      className={styles.botonLimpiarTypeahead}
                      onClick={() => {
                        setSelectedLocalidad([]);
                        updateFilter('CodLoc', '');
                      }}
                      onMouseDown={(e) => e.preventDefault()}
                      title="Limpiar localidad"
                      aria-label="Limpiar localidad"
                    >
                      <Eraser size={14} aria-hidden />
                    </button>
                  )}
                </div>
              </Form.Group>
            </Col>
          </Row>

          <Row className="g-2 mt-2">
            <Col xs={12} sm={4} lg={3}>
              <Form.Group controlId="filtro-tipo-cups">
                <Form.Label className="small mb-1" style={{ color: '#d97706', fontWeight: 600 }}>
                  Tipo de CUPS
                </Form.Label>
                <Form.Select
                  size="sm"
                  value={filters.TipoCups}
                  onChange={(e) => {
                    const tipo = e.target.value;
                    setSelectedCups([]);
                    const newFilters = { ...filters, TipoCups: tipo, Cups: '' };
                    setFilters(newFilters);
                    resetWithFilters(newFilters);
                  }}
                  style={{ borderColor: '#f59e0b', color: '#b45309', fontWeight: 500 }}
                >
                  <option value="electrico">⚡ Electricidad (Luz)</option>
                  <option value="gas">🔥 Gas</option>
                </Form.Select>
              </Form.Group>
            </Col>
            <Col xs={12} sm={8} lg={9}>
              <Form.Group controlId="filtro-cups-local">
                <Form.Label className="small mb-1" style={{ color: '#d97706', fontWeight: 600 }}>
                  Buscar por CUPS ({filters.TipoCups === 'electrico' ? 'Luz' : 'Gas'})
                </Form.Label>
                <div className={styles.grupoTypeaheadConLimpiar}>
                  <Typeahead
                    id="typeahead-cups"
                    labelKey={(option: any) => option.codigoCups || option.CUPsEle || option.CupsGas || option.cups || ''}
                    placeholder={filters.TipoCups === 'electrico' ? "Buscar CUPS eléctrico..." : "Buscar CUPS gas..."}
                    size="sm"
                    options={filters.TipoCups === 'electrico' ? cupsElectricos : cupsGas}
                    selected={selectedCups}
                    onChange={(selected: any[]) => {
                      setSelectedCups(selected);
                      const code = selected[0]
                        ? (selected[0].codigoCups || selected[0].CUPsEle || selected[0].CupsGas || selected[0].cups || '')
                        : '';
                      updateFilter('Cups', code);
                    }}
                    onInputChange={(text: string) => {
                      if (selectedCups.length > 0) {
                        setSelectedCups([]);
                      }
                      updateFilter('Cups', text);
                    }}
                    isLoading={isCargandoCatalogos}
                    emptyLabel="No se encontraron CUPS"
                  />
                  {(selectedCups.length > 0 || filters.Cups) && (
                    <button
                      type="button"
                      className={styles.botonLimpiarTypeahead}
                      onClick={() => {
                        setSelectedCups([]);
                        updateFilter('Cups', '');
                      }}
                      onMouseDown={(e) => e.preventDefault()}
                      title="Limpiar CUPS"
                      aria-label="Limpiar CUPS"
                    >
                      <Eraser size={14} aria-hidden />
                    </button>
                  )}
                </div>
              </Form.Group>
            </Col>
          </Row>
        </Card.Body>
      </Card>

      <div className={styles.gridPuntos}>
        {(puntos as PuntoSuministro[]).map((punto, idx) => (
          <div key={`${punto.CodPunSum}-${idx}`}>
            <PuntoCard
              punto={punto}
              onConsultar={handleView}
              onEditar={handleEdit}
              onBorrar={handleDelete}
              searchTermCups={filters.Cups}
            />
          </div>
        ))}

        {isLoading && (
          <div className={`${styles.gridItemAnchoCompleto} text-center py-4`}>
            <Spinner animation="border" variant="primary" role="status">
              <span className="visually-hidden">Cargando más puntos…</span>
            </Spinner>
            <p className="mt-2 text-muted">Cargando más puntos...</p>
          </div>
        )}

        {hasMore && !isLoading && (
          <div className={styles.gridItemAnchoCompleto}>
            <div ref={sentinelRef} style={{ height: '20px', width: '100%' }} aria-hidden="true" />
          </div>
        )}
      </div>

      {puntos.length === 0 && !isLoading && (
        <div className={styles.estadoVacio}>
          No hay puntos que coincidan con la búsqueda
          {hayFiltrosActivos && (
            <div className="mt-2">
              <Button type="button" size="sm" variant="link" onClick={limpiarFiltros}>
                Limpiar filtros
              </Button>
            </div>
          )}
        </div>
      )}

      {!hasMore && puntos.length > 0 && (
        <div className="text-center text-muted py-4">
          <small>Has visto todos los puntos ({pagination.total.toLocaleString('es-ES')})</small>
        </div>
      )}
    </div>
  );
};

export default PuntoCardsView;
