import { useQuery } from '@tanstack/react-query';
import { useState, type FormEvent } from 'react';
import { useParams } from 'react-router-dom';
import type { PortalRequestStatus } from '@siop/shared';
import { api } from '@/api/client';
import { Button } from '@/components/ui/button';
import { IcoAscenseurs } from '@/components/nav-icons';

/**
 * Écran 6 validé R0 : Karim (gardien, aucune formation, aucun compte) arrive
 * ici en scannant le QR. Équipement prérempli, UN choix critique, suivi sans
 * jargon. Ses signalements vivent sur SON téléphone (référence + jeton).
 */

const CLE_SUIVIS = 'siop.portail.suivis';
interface Suivi { reference: string; token: string; }

const lireSuivis = (): Suivi[] => {
  try {
    return JSON.parse(localStorage.getItem(CLE_SUIVIS) ?? '[]') as Suivi[];
  } catch {
    return [];
  }
};
const ajouterSuivi = (s: Suivi) =>
  localStorage.setItem(CLE_SUIVIS, JSON.stringify([s, ...lireSuivis()].slice(0, 10)));

export default function PagePortail() {
  const { reference } = useParams<{ reference: string }>();
  const [suivis, setSuivis] = useState<Suivi[]>(lireSuivis);
  const [personneBloquee, setPersonneBloquee] = useState(false);
  const [envoye, setEnvoye] = useState(false);
  const [erreur, setErreur] = useState<string | null>(null);

  const { data: asset, isError: refInconnue } = useQuery({
    queryKey: ['portal-asset', reference],
    retry: false,
    queryFn: async () => {
      const { data, response } = await api.GET('/portal/assets/{reference}', {
        params: { path: { reference: reference! } },
      });
      if (!data) throw new Error(String(response.status));
      return data;
    },
  });

  const surEnvoi = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setErreur(null);
    const form = e.currentTarget;
    const description = String(new FormData(form).get('description') ?? '').trim();
    const { data, response } = await api.POST('/portal/requests', {
      body: {
        assetReference: reference!,
        description,
        isPersonTrapped: personneBloquee,
      },
    });
    if (!data) {
      setErreur(
        response.status === 429
          ? 'Trop de signalements envoyés — réessayez dans une minute.'
          : 'Envoi impossible — réessayez ou appelez le numéro affiché en cabine.',
      );
      return;
    }
    ajouterSuivi({ reference: data.reference, token: data.publicToken });
    setSuivis(lireSuivis());
    setPersonneBloquee(false);
    setEnvoye(true);
    form.reset();
  };

  return (
    <div style={{ background: 'var(--fond)', minHeight: '100vh' }}>
      <div className="portail">
        <div className="logo" style={{ color: 'var(--encre)', padding: 0 }}>
          <span className="marque" aria-hidden="true">▲<br />▼</span>
          <div>
            <b style={{ fontSize: 19 }}>SIOP</b>
            <small style={{ color: 'var(--encre-2)' }}>
              Signalement{asset ? ` — ${asset.siteName}` : ''}
            </small>
          </div>
        </div>

        {refInconnue ? (
          <div className="carte">
            <p className="erreur-form">
              Ce QR ne correspond à aucun appareil connu. Vérifiez l'étiquette ou
              appelez le numéro affiché en cabine.
            </p>
          </div>
        ) : (
          <form className="carte flex flex-col gap-3" onSubmit={surEnvoi}>
            <div className="bandeau-detecte">
              <span style={{ color: 'var(--primaire)', width: 18, height: 18, flex: 'none' }}>
                <IcoAscenseurs />
              </span>
              <span>
                <b>Ascenseur {reference}{asset ? ` — ${asset.locationName}` : ''}</b>{' '}
                <span style={{ color: 'var(--encre-2)' }}>(détecté par le QR)</span>
              </span>
            </div>
            <div className="gros-toggle">
              <b>Une personne est-elle bloquée dans la cabine ?</b>
              <button
                type="button"
                className="interrupteur"
                role="switch"
                aria-checked={personneBloquee}
                aria-label="Personne bloquée"
                onClick={() => setPersonneBloquee((v) => !v)}
              />
            </div>
            <div className="champ">
              <label htmlFor="po-desc">Décrivez le problème</label>
              <input
                id="po-desc"
                name="description"
                required
                minLength={3}
                placeholder="Ex. : la porte ne se ferme plus au 3ᵉ étage"
              />
            </div>
            <div className="zone-photo">📷 Ajouter une photo (bientôt disponible)</div>
            {erreur ? <p className="erreur-form" role="alert">{erreur}</p> : null}
            {envoye ? (
              <p style={{ color: 'var(--succes)', fontWeight: 600, fontSize: 13 }} role="status">
                ✓ Signalement envoyé — l'équipe SPELEV est prévenue.
              </p>
            ) : null}
            <Button type="submit" variant="prim" className="justify-center" style={{ padding: 11 }}>
              Envoyer le signalement
            </Button>
          </form>
        )}

        {suivis.length > 0 ? (
          <div className="carte">
            <h2>Mes signalements</h2>
            {suivis.map((s) => (
              <LigneSuivi key={s.reference} suivi={s} />
            ))}
          </div>
        ) : null}
      </div>
    </div>
  );
}

function LigneSuivi({ suivi }: { suivi: Suivi }) {
  const { data } = useQuery({
    queryKey: ['portal-status', suivi.reference],
    refetchInterval: 30_000,
    retry: false,
    queryFn: async () => {
      const { data } = await api.GET('/portal/requests/{reference}/{token}', {
        params: { path: { reference: suivi.reference, token: suivi.token } },
      });
      return data ?? null;
    },
  });
  if (!data) return null;
  return (
    <div className="item-liste" style={{ alignItems: 'flex-start' }}>
      <div>
        <b>{data.description}</b>
        <span className="sous num">
          {data.reference} ·{' '}
          {new Intl.DateTimeFormat('fr-FR', { dateStyle: 'medium' }).format(new Date(data.createdAt))}
        </span>
        {data.status === 'REJECTED' ? (
          <div style={{ fontSize: 12, color: 'var(--encre-2)', marginTop: 4 }}>
            Sans suite : {data.rejectionReason ?? 'voir avec le gestionnaire'}
          </div>
        ) : (
          <Etapes status={data} />
        )}
      </div>
    </div>
  );
}

function Etapes({ status }: { status: PortalRequestStatus }) {
  const franchi = (etape: 'RECEIVED' | 'IN_PROGRESS' | 'RESOLVED') => {
    const ordre = ['RECEIVED', 'IN_PROGRESS', 'RESOLVED'];
    return ordre.indexOf(status.step) >= ordre.indexOf(etape);
  };
  return (
    <div className="suivi-simple">
      <span className={franchi('RECEIVED') ? 'etape fait' : 'etape'}>✓ Reçu</span>
      <span className="lien-e" />
      <span className={franchi('IN_PROGRESS') ? 'etape fait' : 'etape'}>
        {franchi('IN_PROGRESS') ? '✓ ' : ''}Intervention
      </span>
      <span className="lien-e" />
      <span className={franchi('RESOLVED') ? 'etape fait' : 'etape'}>
        {franchi('RESOLVED') ? '✓ ' : ''}Résolu
      </span>
    </div>
  );
}
