import { CameraView, useCameraPermissions } from 'expo-camera';
import { useRef, useState } from 'react';
import { Platform, Pressable, Text, TextInput, View } from 'react-native';
import { useAssetOptions, useCreateRequest } from '@/api/exploitation';
import { analyseScan } from '@/lib/scan';
import { useTokens } from '@/theme/tokens';
import { BoutonTel, ChoixTel } from './ui';

/** Formulaire « Nouvelle demande » — mêmes champs que la modale de
 *  signalement du web (asset via `/assets/options`, accessible même sans
 *  ASSETS.view ; description ; personne bloquée). Utilisé à la fois par
 *  l'onglet du Demandeur et par le Menu des rôles gestion.
 *  Scan QR (R6.6) : raccourci mobile pour resélectionner un équipement déjà
 *  dans son périmètre — résolution UNIQUEMENT contre les options déjà
 *  chargées (déjà filtrées par site pour un Demandeur affecté), jamais un
 *  repli sur le parc complet qui annulerait la restriction. */
export function FormulaireDemande({ surSucces }: { surSucces: (id: string) => void }) {
  const t = useTokens();
  const { data: options } = useAssetOptions();
  const creation = useCreateRequest();
  const [assetId, setAssetId] = useState<string | null>(null);
  const [description, setDescription] = useState('');
  const [personneBloquee, setPersonneBloquee] = useState(false);
  const [scanOuvert, setScanOuvert] = useState(false);
  const [erreurScan, setErreurScan] = useState<string | null>(null);
  const [permission, demanderPermission] = useCameraPermissions();
  const dernierScan = useRef(0);

  const asset = (options ?? []).find((a) => a.id === assetId) ?? null;
  const valide = !!assetId && description.trim().length >= 3;
  const cameraUtilisable = Platform.OS !== 'web' && permission?.granted;

  const surScan = ({ data }: { data: string }) => {
    const maintenant = Date.now();
    if (maintenant - dernierScan.current < 1500) return; // anti-rafale
    dernierScan.current = maintenant;
    const reference = analyseScan(data);
    const trouve = reference
      ? (options ?? []).find((a) => a.reference.toUpperCase() === reference)
      : null;
    if (!trouve) {
      setErreurScan("Cet appareil n'existe pas ou n'est pas dans votre périmètre.");
      return;
    }
    setErreurScan(null);
    setAssetId(trouve.id);
    setScanOuvert(false);
  };

  const envoyer = () => {
    if (!assetId) return;
    creation.mutate(
      { assetId, description: description.trim(), isPersonTrapped: personneBloquee },
      { onSuccess: (r) => surSucces(r.id) },
    );
  };

  return (
    <View style={{ gap: 12 }}>
      <ChoixTel
        libelle="Équipement"
        requis
        valeur={asset ? { id: asset.id, label: `${asset.reference} — ${asset.siteName}` } : null}
        options={(options ?? []).map((a) => ({ id: a.id, label: `${a.reference} — ${a.siteName}` }))}
        surChoix={setAssetId}
      />
      {scanOuvert ? (
        <View style={{ gap: 8 }}>
          {cameraUtilisable ? (
            <View style={{ height: 220, borderRadius: 12, overflow: 'hidden' }}>
              <CameraView
                style={{ flex: 1 }}
                barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
                onBarcodeScanned={surScan}
              />
            </View>
          ) : (
            <View
              style={{
                height: 220,
                borderRadius: 12,
                backgroundColor: '#131c2c',
                alignItems: 'center',
                justifyContent: 'center',
                gap: 10,
                padding: 16,
              }}
            >
              <Text
                style={{
                  color: '#dfe7f2',
                  fontFamily: 'Manrope_600SemiBold',
                  fontSize: 12.5,
                  textAlign: 'center',
                }}
              >
                {Platform.OS === 'web'
                  ? 'Caméra indisponible sur web.'
                  : "Visez le QR de l'étiquette de cabine."}
              </Text>
              {Platform.OS !== 'web' && !permission?.granted ? (
                <BoutonTel libelle="Autoriser la caméra" surAppui={() => void demanderPermission()} />
              ) : null}
            </View>
          )}
          <BoutonTel libelle="Annuler le scan" variante="gris" surAppui={() => setScanOuvert(false)} />
        </View>
      ) : (
        <BoutonTel
          libelle="📷 Scanner l'étiquette"
          variante="contour"
          surAppui={() => {
            setErreurScan(null);
            setScanOuvert(true);
          }}
        />
      )}
      {erreurScan ? (
        <Text style={{ color: t.danger, fontFamily: 'Manrope_600SemiBold', fontSize: 12.5 }}>
          {erreurScan}
        </Text>
      ) : null}
      <View style={{ gap: 4 }}>
        <Text style={{ fontFamily: 'Manrope_700Bold', fontSize: 11, color: t.encre2 }}>
          Description <Text style={{ color: t.danger }}>*</Text>
        </Text>
        <TextInput
          accessibilityLabel="Description du problème"
          placeholder="Ex. : la porte ne se ferme plus au 3ᵉ étage"
          placeholderTextColor={t.encre3}
          multiline
          value={description}
          onChangeText={setDescription}
          style={{
            borderWidth: 1.5,
            borderColor: t.bordureForte,
            borderRadius: 9,
            paddingHorizontal: 10,
            paddingVertical: 9,
            minHeight: 64,
            color: t.encre,
            fontFamily: 'Manrope_600SemiBold',
            fontSize: 13,
            textAlignVertical: 'top',
          }}
        />
      </View>
      <Pressable
        accessibilityRole="switch"
        accessibilityLabel="Une personne est-elle bloquée ?"
        accessibilityState={{ checked: personneBloquee }}
        onPress={() => setPersonneBloquee((v) => !v)}
        style={{
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'space-between',
          backgroundColor: personneBloquee ? t.prioBloqueFond : t.surface,
          borderColor: personneBloquee ? t.danger : t.bordure,
          borderWidth: 1,
          borderRadius: 10,
          padding: 12,
        }}
      >
        <Text
          style={{
            fontFamily: 'Manrope_700Bold',
            fontSize: 13,
            color: personneBloquee ? t.danger : t.encre,
          }}
        >
          Une personne est-elle bloquée ?
        </Text>
        <Text style={{ fontFamily: 'Manrope_800ExtraBold', fontSize: 13, color: personneBloquee ? t.danger : t.encre3 }}>
          {personneBloquee ? 'OUI' : 'NON'}
        </Text>
      </Pressable>
      {creation.isError ? (
        <Text style={{ color: t.danger, fontFamily: 'Manrope_600SemiBold', fontSize: 12.5 }}>
          {creation.error.message}
        </Text>
      ) : null}
      <BoutonTel
        libelle="Envoyer la demande"
        desactive={!valide || creation.isPending}
        surAppui={envoyer}
      />
    </View>
  );
}
