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

function scoreLabel(value, level, distance) {
  if (level === 'high')                          return 'Impact';
  if (level === 'medium')                        return 'Risque';
  if (value >= 15 && distance != null && distance < 100) return 'Veille';
  return 'OK';
}
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, score, distance) {
  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' };
  if ((score ?? 0) >= 15 && distance != null && distance < 100)
                       return { icon: '👁',  label: 'Sargasses en surveillance',    cls: 'eta--watch' };
  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,
        breakdown:  data.horizons[activeStep].breakdown,
      } : 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), data?.score?.value, data?.score?.distance);
                  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}`}>
                  <p className="spot-panel__gauge-header">Indice de risque</p>
                  <span className="spot-panel__gauge-label">{scoreLabel(displayScore.value, lvl, displayScore.distance)}</span>
                  <div className="spot-panel__gauge-track">
                    <div
                      className="spot-panel__gauge-fill"
                      style={{ width: `${displayScore.value}%` }}
                    />
                  </div>
                  <p className="spot-panel__gauge-hint">{displayScore.value} / 100</p>
                </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>

                <ScoreBreakdown breakdown={displayScore.breakdown} />

                {activeStep === 'now' && <PatchList patches={data?.patches} />}
              </>
            )
        )}
      </div>

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

function PatchList({ patches }) {
  if (!patches?.length) return null;

  // Échelle visuelle : 100 km = barre pleine
  const MAX_KM = 100;

  return (
    <div className="patch-list">
      <p className="patch-list__title">
        {patches.length} banc{patches.length > 1 ? 's' : ''} de sargasses détecté{patches.length > 1 ? 's' : ''}
      </p>
      {patches.map((p, i) => {
        const pct = Math.min((p.distanceKm / MAX_KM) * 100, 100);
        const sizeLabel = p.areaKm2 >= 10
          ? `${p.areaKm2} km²`
          : `${p.areaKm2} km²`;
        return (
          <div key={i} className="patch-list__row">
            <span className="patch-list__dist">{p.distanceKm} km</span>
            <div className="patch-list__track">
              <div className="patch-list__fill" style={{ width: `${pct}%` }} />
            </div>
            <span className="patch-list__area">{sizeLabel}</span>
          </div>
        );
      })}
    </div>
  );
}

const BREAKDOWN_ITEMS = [
  { key: 'distance', label: 'Distance',  max: 40, icon: '📏' },
  { key: 'density',  label: 'Densité',   max: 30, icon: '🌿' },
  { key: 'velocity', label: 'Vitesse',   max: 20, icon: '➡' },
  { key: 'trend',    label: 'Tendance',  max: 10, icon: '📈' },
];

function ScoreBreakdown({ breakdown }) {
  if (!breakdown) return null;

  return (
    <div className="score-breakdown">
      <p className="score-breakdown__title">Détail du score</p>
      {BREAKDOWN_ITEMS.map(({ key, label, max, icon }) => {
        const val = breakdown[key] ?? 0;
        const pct = max > 0 ? (val / max) * 100 : 0;
        return (
          <div key={key} className="score-breakdown__row">
            <span className="score-breakdown__icon">{icon}</span>
            <span className="score-breakdown__label">{label}</span>
            <div className="score-breakdown__track">
              <div className="score-breakdown__fill" style={{ width: `${pct}%` }} />
            </div>
            <span className="score-breakdown__value">
              {val}<span className="score-breakdown__max">/{max}</span>
            </span>
          </div>
        );
      })}
    </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>
  );
}
