import { router } from 'expo-router';
import { useState } from 'react';
import { FlatList, Text, TextInput, View } from 'react-native';
import type { RequestSummary } from '@siop/shared';
import {
  useApproveRequest,
  useRejectRequest,
  useRequests,
} from '@/api/exploitation';
import { useUsers } from '@/api/pilotage';
import { usePermissions } from '@/auth/use-permissions';
import { useTokens, type Tokens } from '@/theme/tokens';
import { BoutonTel, ChoixTel } from './ui';

/** Panneau Demandes — UN SEUL composant pour tous les rôles (maquette
 *  « mobile ouvert à tous les rôles », écran 5) : le Demandeur y crée et
 *  suit SES demandes ; Gestionnaire/Dispatcher/Administrateur y approuvent
 *  ou rejettent (motif obligatoire, comme au web) ; Vue seule consulte sans
 *  bouton. L'API renvoie déjà la liste correctement scopée (ADR-003) — ce
 *  composant affiche ce qu'on lui donne et ne propose que les actions
 *  permises par `can(...)`. */
export function PanneauDemandes() {
  const t = useTokens();
  const { can } = usePermissions();
  const { data: requests } = useRequests();
  const peutTraiter = can('REQUESTS', 'edit');
  const peutCreer = can('REQUESTS', 'create');
  const toutes = requests ?? [];
  const aTraiter = toutes.filter((r) => r.status === 'RECEIVED').length;

  return (
    <View style={{ flex: 1, gap: 10 }}>
      <View style={{ flexDirection: 'row', alignItems: 'baseline' }}>
        <Text style={{ fontFamily: 'Manrope_800ExtraBold', fontSize: 19, color: t.encre }}>
          Demandes
        </Text>
        <Text style={{ marginLeft: 'auto', fontFamily: 'Manrope_600SemiBold', fontSize: 11, color: t.encre3 }}>
          {aTraiter} à traiter · {toutes.length} au total
        </Text>
      </View>
      {peutCreer ? (
        <BoutonTel libelle="+ Nouvelle demande" surAppui={() => router.push('/demandes/nouvelle')} />
      ) : null}
      <FlatList
        data={toutes}
        keyExtractor={(r) => r.id}
        contentContainerStyle={{ gap: 8, paddingBottom: 12 }}
        ListEmptyComponent={
          <Text style={{ color: t.encre3, fontFamily: 'Manrope_600SemiBold', padding: 16, textAlign: 'center' }}>
            Aucune demande pour l'instant.
          </Text>
        }
        renderItem={({ item: r }) => <CarteDemande demande={r} peutTraiter={peutTraiter} />}
      />
    </View>
  );
}

const STYLE_STATUT: Record<RequestSummary['status'], (t: Tokens) => [string, string]> = {
  RECEIVED: (t) => [t.stAttente, t.stAttenteFond],
  APPROVED: (t) => [t.stTermine, t.stTermineFond],
  REJECTED: (t) => [t.stAnnule, t.stAnnuleFond],
};
const LABEL_STATUT: Record<RequestSummary['status'], string> = {
  RECEIVED: 'Reçue',
  APPROVED: 'Approuvée',
  REJECTED: 'Rejetée',
};

function CarteDemande({ demande: r, peutTraiter }: { demande: RequestSummary; peutTraiter: boolean }) {
  const t = useTokens();
  const { data: users } = useUsers();
  const approbation = useApproveRequest();
  const rejet = useRejectRequest();
  // Un seul panneau ouvert à la fois : approbation (avec assignation — ce
  // n'est pas au Gestionnaire d'agir comme un technicien, il délègue) ou
  // rejet (motif obligatoire). null = fermé, les deux boutons côte à côte.
  const [panneau, setPanneau] = useState<'approuver' | 'rejeter' | null>(null);
  const [motif, setMotif] = useState('');
  const [assigneId, setAssigneId] = useState<string | null>(null);

  const techniciens = (users ?? []).filter(
    (u) => u.status === 'active' && u.role.name.startsWith('Technicien'),
  );
  const technicien = techniciens.find((tt) => tt.id === assigneId) ?? null;

  const [enc, fond] = STYLE_STATUT[r.status](t);
  const enCours = r.status === 'RECEIVED';

  return (
    <View
      style={{
        backgroundColor: t.surface,
        borderColor: r.isPersonTrapped && enCours ? t.danger : t.bordure,
        borderWidth: r.isPersonTrapped && enCours ? 1.5 : 1,
        borderRadius: 12,
        padding: 12,
        gap: 6,
      }}
    >
      <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
        <Text
          style={{
            flex: 1,
            fontFamily: 'Manrope_700Bold',
            fontSize: 10.5,
            letterSpacing: 0.6,
            textTransform: 'uppercase',
            color: t.encre2,
          }}
        >
          {r.reference}
        </Text>
        <Text
          style={{
            fontFamily: 'Manrope_700Bold',
            fontSize: 10.5,
            color: enc,
            backgroundColor: fond,
            paddingHorizontal: 8,
            paddingVertical: 2,
            borderRadius: 999,
            overflow: 'hidden',
          }}
        >
          {LABEL_STATUT[r.status]}
        </Text>
      </View>
      <Text style={{ fontFamily: 'Manrope_700Bold', fontSize: 14, color: t.encre }}>
        {r.isPersonTrapped ? '⚠ ' : ''}
        {r.description}
      </Text>
      <Text style={{ fontFamily: 'Manrope_400Regular', fontSize: 12, color: t.encre2 }}>
        Asc. {r.assetReference} — {r.siteName} · {r.requesterLabel}
      </Text>
      {r.rejectionReason ? (
        <Text style={{ fontFamily: 'Manrope_600SemiBold', fontSize: 12, color: t.danger }}>
          Motif du rejet : {r.rejectionReason}
        </Text>
      ) : null}

      {peutTraiter && enCours ? (
        panneau === null ? (
          <View style={{ flexDirection: 'row', gap: 8, marginTop: 4 }}>
            <View style={{ flex: 1 }}>
              <BoutonTel libelle="Approuver → OT" variante="vert" surAppui={() => setPanneau('approuver')} />
            </View>
            <View style={{ flex: 1 }}>
              <BoutonTel libelle="Rejeter" variante="gris" surAppui={() => setPanneau('rejeter')} />
            </View>
          </View>
        ) : panneau === 'approuver' ? (
          <View style={{ gap: 6, marginTop: 4 }}>
            <ChoixTel
              libelle="Assigner à"
              valeur={technicien ? { id: technicien.id, label: technicien.displayName } : null}
              options={techniciens.map((tt) => ({ id: tt.id, label: tt.displayName }))}
              surChoix={setAssigneId}
            />
            <View style={{ flexDirection: 'row', gap: 8 }}>
              <View style={{ flex: 1 }}>
                <BoutonTel
                  libelle="Annuler"
                  variante="contour"
                  surAppui={() => {
                    setPanneau(null);
                    setAssigneId(null);
                  }}
                />
              </View>
              <View style={{ flex: 1 }}>
                <BoutonTel
                  libelle="Confirmer l'approbation"
                  variante="vert"
                  desactive={approbation.isPending}
                  surAppui={() =>
                    approbation.mutate(
                      {
                        id: r.id,
                        priority: r.isPersonTrapped ? 'PERSON_TRAPPED' : 'HIGH',
                        assigneeIds: assigneId ? [assigneId] : undefined,
                      },
                      { onSuccess: () => setPanneau(null) },
                    )
                  }
                />
              </View>
            </View>
          </View>
        ) : (
          <View style={{ gap: 6, marginTop: 4 }}>
            <TextInput
              accessibilityLabel="Motif du rejet"
              placeholder="Motif (lisible par le demandeur) *"
              placeholderTextColor={t.encre3}
              value={motif}
              onChangeText={setMotif}
              style={{
                borderWidth: 1.5,
                borderColor: t.bordureForte,
                borderRadius: 9,
                paddingHorizontal: 10,
                paddingVertical: 9,
                color: t.encre,
                fontFamily: 'Manrope_600SemiBold',
                fontSize: 13,
              }}
            />
            <View style={{ flexDirection: 'row', gap: 8 }}>
              <View style={{ flex: 1 }}>
                <BoutonTel
                  libelle="Annuler"
                  variante="contour"
                  surAppui={() => {
                    setPanneau(null);
                    setMotif('');
                  }}
                />
              </View>
              <View style={{ flex: 1 }}>
                <BoutonTel
                  libelle="Confirmer le rejet"
                  desactive={motif.trim().length < 3}
                  surAppui={() =>
                    rejet.mutate(
                      { id: r.id, reason: motif.trim() },
                      { onSuccess: () => setPanneau(null) },
                    )
                  }
                />
              </View>
            </View>
          </View>
        )
      ) : null}
    </View>
  );
}
