import { useEffect, useState } from 'react';
import { api } from '../../api/client';
import usePushSubscription from '../../hooks/usePushSubscription';
import './SpotPanel.css';

const LEVEL_LABEL = { low: 'OK', medium: 'Risque', high: 'Impact' };
const TYPE_ICON   = { beach: '🏖', port: '⚓', surf: '🏄', fishing: '🎣' };

const TREND_CONFIG = {
  increasing: { icon: '📈', label: 'Situation en dégradation', cls: 'trend--bad'  },
  stable:     { icon: '➡️', label: 'Situation stable',         cls: 'trend--neutral' },
  decreasing: { icon: '📉', label: 'Amélioration en cours',    cls: 'trend--good' },
};

const ETA_BUFFER_KM = 5;

function computeEta(score, horizons) {
  if (score?.distance != null && score.distance < ETA_BUFFER_KM) return 0;
  for (const h of [6, 12, 24, 48]) {
    const horizon = horizons?.[`h${h}`];
    if (horizon?.distanceKm != null && horizon.distanceKm < ETA_BUFFER_KM) return h;
  }
  return null;
}

function etaLabel(etaHours) {
  if (etaHours === 0)  return { icon: '🚨', label: 'Impact en cours',           cls: 'eta--now'  };
  if (etaHours === 6)  return { icon: '⚠️',  label: 'Impact prévu dans ~6h',     cls: 'eta--soon' };
  if (etaHours === 12) return { icon: '⚠️',  label: 'Impact prévu dans ~12h',    cls: 'eta--soon' };
  if (etaHours === 24) return { icon: '🕐',  label: 'Impact prévu dans ~24h',    cls: 'eta--later' };
  if (etaHours === 48) return { icon: '🕐',  label: 'Impact prévu dans ~48h',    cls: 'eta--later' };
  return                       { icon: '✅',  label: 'Aucun impact prévu (48h)',  cls: 'eta--safe' };
}

const HORIZON_LABELS = { now: 'Maintenant', h6: '+6h', h12: '+12h', h24: '+24h', h48: '+48h' };

export default function SpotPanel({ spot, activeStep, onClose }) {
  const [data,    setData]    = useState(undefined);
  const [error,   setError]   = useState(null);

  useEffect(() => {
    if (!spot) return;
    setData(undefined);
    setError(null);

    api.spots.score(spot.id)
      .then(d => setData(d))
      .catch(() => setError('Impossible de charger le score.'));
  }, [spot?.id]);

  if (!spot) return null;

  // Score à afficher selon l'étape active
  const displayScore = activeStep === 'now'
    ? data?.score
    : (data?.horizons?.[activeStep] ? {
        value:      data.horizons[activeStep].score,
        level:      data.horizons[activeStep].level,
        distance:   data.horizons[activeStep].distanceKm,
        confidence: data.horizons[activeStep].confidence,
      } : null);

  const lvl = displayScore?.level;

  return (
    <div className="spot-panel">
      <button className="spot-panel__close" onClick={onClose} aria-label="Fermer">✕</button>

      <div className="spot-panel__header">
        <span className="spot-panel__icon">{TYPE_ICON[spot.type] ?? '📍'}</span>
        <div>
          <h2 className="spot-panel__name">{spot.name}</h2>
          <p className="spot-panel__region">{spot.region}</p>
        </div>
      </div>

      <div className="spot-panel__horizon-label">
        {HORIZON_LABELS[activeStep] ?? activeStep}
        {activeStep !== 'now' && displayScore?.confidence != null && (
          <span className="spot-panel__confidence">
            Confiance : {Math.round(displayScore.confidence * 100)}%
          </span>
        )}
      </div>

      <div className="spot-panel__score">
        {data === undefined && <p className="spot-panel__loading">Chargement…</p>}
        {error && <p className="spot-panel__error">{error}</p>}

        {data !== undefined && !error && (
          displayScore === null
            ? <p className="spot-panel__no-data">Aucune donnée pour cet horizon.</p>
            : (
              <>
                {activeStep === 'now' && (() => {
                  const eta = etaLabel(computeEta(data?.score, data?.horizons));
                  return (
                    <div className={`spot-panel__eta ${eta.cls}`}>
                      <span className="spot-panel__eta-icon">{eta.icon}</span>
                      <span className="spot-panel__eta-label">{eta.label}</span>
                    </div>
                  );
                })()}

                <div className={`spot-panel__gauge gauge--${lvl}`}>
                  <div className="spot-panel__gauge-top">
                    <span className="spot-panel__gauge-label">{LEVEL_LABEL[lvl] ?? lvl}</span>
                    <span className="spot-panel__gauge-score">
                      {displayScore.value}
                      <span className="spot-panel__gauge-max">/100</span>
                    </span>
                  </div>
                  <div className="spot-panel__gauge-track">
                    <div
                      className="spot-panel__gauge-fill"
                      style={{ width: `${displayScore.value}%` }}
                    />
                  </div>
                </div>

                {activeStep === 'now' && displayScore.trend && (() => {
                  const t = TREND_CONFIG[displayScore.trend] ?? TREND_CONFIG.stable;
                  return (
                    <div className={`spot-panel__trend ${t.cls}`}>
                      <span className="spot-panel__trend-icon">{t.icon}</span>
                      <span className="spot-panel__trend-label">{t.label}</span>
                    </div>
                  );
                })()}

                <dl className="spot-panel__details">
                  {displayScore.distance != null && (
                    <><dt>Distance sargasses</dt><dd>{displayScore.distance} km</dd></>
                  )}
                  {activeStep === 'now' && displayScore.computedAt && (
                    <><dt>Calculé le</dt>
                    <dd>{new Date(displayScore.computedAt).toLocaleString('fr-FR')}</dd></>
                  )}
                </dl>
              </>
            )
        )}
      </div>

      <FeedbackButton spot={spot} />
      <PushButton spotId={spot.id} />
    </div>
  );
}

function FeedbackButton({ spot }) {
  const [sent,    setSent]    = useState(false);
  const [loading, setLoading] = useState(false);

  const submit = async (hasSeaweed) => {
    if (loading || sent) return;
    setLoading(true);
    if (spot.latitude != null && spot.longitude != null) {
      await api.feedback.create({
        lat: spot.latitude, lng: spot.longitude,
        hasSeaweed, coastalPointId: spot.id,
      }).catch(console.error);
    }
    setLoading(false);
    setSent(true);
  };

  if (sent) return <p className="spot-panel__feedback-thanks">Merci pour votre retour !</p>;

  return (
    <div className="spot-panel__feedback">
      <p>Vous êtes sur place ?</p>
      <div className="spot-panel__feedback-btns">
        <button onClick={() => submit(true)}  disabled={loading}>✅ Je vois des sargasses</button>
        <button onClick={() => submit(false)} disabled={loading}>❌ Pas de sargasses</button>
      </div>
    </div>
  );
}

function PushButton({ spotId }) {
  const { supported, subscribed, loading, error, toggle } = usePushSubscription(spotId);

  if (!supported) return null;

  return (
    <div className="spot-panel__push">
      <button
        className={`spot-panel__push-btn ${subscribed ? 'spot-panel__push-btn--active' : ''}`}
        onClick={toggle}
        disabled={loading}
        aria-pressed={subscribed}
      >
        {loading ? '…' : subscribed ? '🔔 Alertes activées' : '🔕 Activer les alertes'}
      </button>
      {error && <p className="spot-panel__push-error">{error}</p>}
    </div>
  );
}
