import { Ionicons } from '@expo/vector-icons';
import { router, useLocalSearchParams } from 'expo-router';
import { useLayoutEffect, useMemo, useState, useEffect } from 'react';
import {
  Alert,
  Pressable,
  ScrollView,
  StyleSheet,
  Switch,
  Text,
  View,
} from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { LabeledField } from '../../src/components/LabeledField';
import { PrimaryButton } from '../../src/components/PrimaryButton';
import { useApp, useVisitFindings } from '../../src/context/AppContext';
import { colors } from '../../src/theme/colors';
import type {
  DossierRow,
  DossierVisitFindingRow,
  VisitFindingDefinitionRow,
} from '../../src/data/types';
import { useDossierJuge } from '../../src/hooks/useDossierJuge';
import { matchInvestisseurs } from '../../src/services/matchInvestors';
import { shareTeaserPdf } from '../../src/services/teaserPdf';
import { MIN_NET_MARGIN_PCT } from '../../src/core/juge';

type TabKey = 'dash' | 'money' | 'visit' | 'flash';

const TABS: { key: TabKey; label: string }[] = [
  { key: 'dash', label: 'Feu' },
  { key: 'money', label: 'Finances' },
  { key: 'visit', label: 'Visite' },
  { key: 'flash', label: 'Flash' },
];

export default function DossierDetailScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const dossierId = typeof id === 'string' ? id : id?.[0];
  const navigation = useNavigation();
  const insets = useSafeAreaInsets();
  const app = useApp();
  const [tab, setTab] = useState<TabKey>('dash');

  const dossier = useMemo(
    () => app.dossiers.find((d) => d.id === dossierId),
    [app.dossiers, dossierId],
  );

  const findings = useVisitFindings(dossierId);
  const juge = useDossierJuge(dossier, findings, app.definitions);

  useLayoutEffect(() => {
    navigation.setOptions({
      title: dossier?.title ?? 'Dossier',
      headerRight: () => (
        <Pressable
          accessibilityRole="button"
          hitSlop={12}
          onPress={() => {
            if (!dossierId) return;
            Alert.alert(
              'Supprimer le dossier',
              'Cette action est irréversible.',
              [
                { text: 'Annuler', style: 'cancel' },
                {
                  text: 'Supprimer',
                  style: 'destructive',
                  onPress: () => {
                    void app.deleteDossier(dossierId).then(() => router.back());
                  },
                },
              ],
            );
          }}
        >
          <Ionicons name="trash-outline" size={22} color={colors.danger} />
        </Pressable>
      ),
    });
  }, [navigation, dossier?.title, dossierId, app.deleteDossier]);

  if (!dossierId || !dossier || !juge) {
    return (
      <View style={[styles.center, { paddingTop: insets.top }]}>
        <Text style={styles.muted}>Dossier introuvable.</Text>
        <PrimaryButton title="Retour" onPress={() => router.back()} />
      </View>
    );
  }

  const matches = matchInvestisseurs(dossier, juge.result, app.investisseurs);

  const dashBg =
    juge.result.trafficLight === 'red'
      ? '#2d1418'
      : juge.result.trafficLight === 'orange'
        ? '#2a2310'
        : juge.result.trafficLight === 'green_flash_dvf'
          ? '#102a18'
          : '#10221c';

  return (
    <View style={styles.root}>
      <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        style={styles.tabBar}
        contentContainerStyle={styles.tabBarInner}
      >
        {TABS.map((t) => (
          <Pressable
            key={t.key}
            onPress={() => setTab(t.key)}
            style={[styles.tabChip, tab === t.key && styles.tabChipOn]}
          >
            <Text style={[styles.tabText, tab === t.key && styles.tabTextOn]}>
              {t.label}
            </Text>
          </Pressable>
        ))}
      </ScrollView>

      {tab === 'dash' ? (
        <ScrollView
          contentContainerStyle={{
            padding: 16,
            paddingBottom: insets.bottom + 24,
          }}
        >
          <View style={[styles.hero, { backgroundColor: dashBg }]}>
            <Text style={styles.heroLabel}>Score deal</Text>
            <Text style={styles.heroScore}>{juge.result.scoreDeal}</Text>
            <Text style={styles.heroSub}>
              Marge nette : {(juge.result.netMarginPct * 100).toFixed(1)} % (seuil
              achat : {(MIN_NET_MARGIN_PCT * 100).toFixed(0)} %)
            </Text>
            <Text style={styles.heroSub}>
              Feu : {juge.result.trafficLight} — DVF flash :{' '}
              {juge.result.dvfUnderMarketFlash ? 'oui' : 'non'}
            </Text>
          </View>
          <View style={styles.card}>
            <Text style={styles.cardTitle}>Synthèse</Text>
            <Row label="Investi (est.)" value={`${Math.round(juge.result.totalInvested).toLocaleString('fr-FR')} €`} />
            <Row label="Produit net revente" value={`${Math.round(juge.result.netResaleProceeds).toLocaleString('fr-FR')} €`} />
            <Row label="TVA sur marge (est.)" value={`${Math.round(juge.result.vatOnMargin).toLocaleString('fr-FR')} €`} />
            <Row label="Marge nette" value={`${Math.round(juge.result.netMarginAfterVat).toLocaleString('fr-FR')} €`} />
            <Row
              label="Break-even revente"
              value={
                Number.isFinite(juge.result.breakEvenResalePrice)
                  ? `${Math.round(juge.result.breakEvenResalePrice).toLocaleString('fr-FR')} €`
                  : '—'
              }
            />
          </View>
          <PrimaryButton
            title="Marquer « sous promesse »"
            variant="ghost"
            onPress={() => void app.setDossierStatus(dossier.id, 'under_promise')}
            containerStyle={{ marginTop: 8 }}
          />
        </ScrollView>
      ) : null}

      {tab === 'money' ? (
        <FinancesEditor dossier={dossier} onSave={(patch) => void app.updateDossier(dossier.id, patch)} />
      ) : null}

      {tab === 'visit' ? (
        <VisiteTab
          definitions={app.definitions}
          findings={findings}
          onToggle={(code, checked) =>
            void app.toggleFinding(dossier.id, code, checked)
          }
          checklistEUR={juge.checklistWorks}
          maxPurchase={juge.maxPurchase}
        />
      ) : null}

      {tab === 'flash' ? (
        <ScrollView
          contentContainerStyle={{
            padding: 16,
            paddingBottom: insets.bottom + 24,
          }}
        >
          {dossier.status !== 'under_promise' ? (
            <Text style={styles.muted}>
              Verrouillez le dossier (« sous promesse ») depuis l’onglet Feu pour
              activer le teaser investisseur.
            </Text>
          ) : (
            <>
              <Text style={styles.cardTitle}>Investisseurs (top 5 match)</Text>
              {matches.length === 0 ? (
                <Text style={styles.muted}>Aucun match — ajustez critères ou dossier.</Text>
              ) : (
                matches.map((m) => (
                  <View key={m.id} style={styles.matchRow}>
                    <Text style={styles.matchName}>{m.display_name}</Text>
                    {m.email ? (
                      <Text style={styles.muted}>{m.email}</Text>
                    ) : null}
                  </View>
                ))
              )}
              <PrimaryButton
                title="Générer & partager le teaser PDF"
                containerStyle={{ marginTop: 16 }}
                onPress={() =>
                  void shareTeaserPdf(
                    dossier,
                    juge.result,
                    matches.map((m) => m.display_name),
                  )
                }
              />
            </>
          )}
        </ScrollView>
      ) : null}
    </View>
  );
}

function Row({ label, value }: { label: string; value: string }) {
  return (
    <View style={styles.row}>
      <Text style={styles.rowLabel}>{label}</Text>
      <Text style={styles.rowValue}>{value}</Text>
    </View>
  );
}

function FinancesEditor({
  dossier,
  onSave,
}: {
  dossier: DossierRow;
  onSave: (patch: Partial<DossierRow>) => void;
}) {
  const insets = useSafeAreaInsets();
  const [title, setTitle] = useState(dossier.title);
  const [address, setAddress] = useState(dossier.address_line ?? '');
  const [city, setCity] = useState(dossier.city ?? '');
  const [postal, setPostal] = useState(dossier.postal_code ?? '');
  const [surface, setSurface] = useState(String(dossier.surface_m2 ?? ''));
  const [purchase, setPurchase] = useState(String(dossier.purchase_price_target ?? ''));
  const [resale, setResale] = useState(String(dossier.resale_price_estimate ?? ''));
  const [dvf, setDvf] = useState(String(dossier.dvf_reference_price_m2 ?? ''));
  const [works, setWorks] = useState(String(dossier.works_estimate_total ?? ''));
  const [miscA, setMiscA] = useState(String(dossier.misc_acquisition_cost ?? ''));
  const [miscS, setMiscS] = useState(String(dossier.misc_sale_cost ?? ''));
  const [carryM, setCarryM] = useState(String(dossier.carrying_months ?? 6));
  const [carryR, setCarryR] = useState(String(dossier.carrying_annual_rate ?? 0.05));
  const [dpe, setDpe] = useState(dossier.dpe_class ?? '');
  const [pluZone, setPluZone] = useState(dossier.plu_zone_code ?? '');
  const [pluNotes, setPluNotes] = useState(dossier.plu_notes ?? '');
  const [parcelDiv, setParcelDiv] = useState(dossier.parcel_subdivision_candidate);
  const [deficitFoncier, setDeficitFoncier] = useState(
    dossier.deficit_foncier_candidate,
  );

  useEffect(() => {
    setTitle(dossier.title);
    setAddress(dossier.address_line ?? '');
    setCity(dossier.city ?? '');
    setPostal(dossier.postal_code ?? '');
    setSurface(String(dossier.surface_m2 ?? ''));
    setPurchase(String(dossier.purchase_price_target ?? ''));
    setResale(String(dossier.resale_price_estimate ?? ''));
    setDvf(String(dossier.dvf_reference_price_m2 ?? ''));
    setWorks(String(dossier.works_estimate_total ?? ''));
    setMiscA(String(dossier.misc_acquisition_cost ?? ''));
    setMiscS(String(dossier.misc_sale_cost ?? ''));
    setCarryM(String(dossier.carrying_months ?? 6));
    setCarryR(String(dossier.carrying_annual_rate ?? 0.05));
    setDpe(dossier.dpe_class ?? '');
    setPluZone(dossier.plu_zone_code ?? '');
    setPluNotes(dossier.plu_notes ?? '');
    setParcelDiv(dossier.parcel_subdivision_candidate);
    setDeficitFoncier(dossier.deficit_foncier_candidate);
  }, [
    dossier.id,
    dossier.updated_at,
    dossier.title,
    dossier.address_line,
    dossier.city,
    dossier.postal_code,
    dossier.surface_m2,
    dossier.purchase_price_target,
    dossier.resale_price_estimate,
    dossier.dvf_reference_price_m2,
    dossier.works_estimate_total,
    dossier.misc_acquisition_cost,
    dossier.misc_sale_cost,
    dossier.carrying_months,
    dossier.carrying_annual_rate,
    dossier.dpe_class,
    dossier.plu_zone_code,
    dossier.plu_notes,
    dossier.parcel_subdivision_candidate,
    dossier.deficit_foncier_candidate,
  ]);

  const parseNum = (s: string) => Number(s.replace(',', '.').replace(/\s/g, ''));

  return (
    <ScrollView
      contentContainerStyle={{
        padding: 16,
        paddingBottom: insets.bottom + 24,
      }}
    >
      <LabeledField label="Titre du dossier" value={title} onChangeText={setTitle} />
      <LabeledField label="Adresse" value={address} onChangeText={setAddress} />
      <LabeledField label="Ville" value={city} onChangeText={setCity} />
      <LabeledField label="Code postal" value={postal} onChangeText={setPostal} />
      <LabeledField
        label="Surface (m²)"
        keyboardType="decimal-pad"
        value={surface}
        onChangeText={setSurface}
      />
      <LabeledField
        label="Prix d'achat cible (€)"
        keyboardType="number-pad"
        value={purchase}
        onChangeText={setPurchase}
      />
      <LabeledField
        label="Prix de revente estimé (€)"
        keyboardType="number-pad"
        value={resale}
        onChangeText={setResale}
      />
      <LabeledField
        label="DVF réf. (€/m²)"
        keyboardType="decimal-pad"
        value={dvf}
        onChangeText={setDvf}
      />
      <LabeledField
        label="Travaux estimés hors checklist (€)"
        keyboardType="number-pad"
        value={works}
        onChangeText={setWorks}
      />
      <LabeledField
        label="Frais d'achat divers (€)"
        keyboardType="number-pad"
        value={miscA}
        onChangeText={setMiscA}
      />
      <LabeledField
        label="Frais de vente divers (€)"
        keyboardType="number-pad"
        value={miscS}
        onChangeText={setMiscS}
      />
      <LabeledField
        label="Portage (mois)"
        keyboardType="number-pad"
        value={carryM}
        onChangeText={setCarryM}
      />
      <LabeledField
        label="Taux portage annuel (ex: 0.055)"
        keyboardType="decimal-pad"
        value={carryR}
        onChangeText={setCarryR}
      />
      <LabeledField
        label="DPE (A–G)"
        autoCapitalize="characters"
        maxLength={1}
        value={dpe}
        onChangeText={(t) => setDpe(t.toUpperCase())}
      />
      <Text style={styles.sectionLabel}>Urbanisme & stratégie</Text>
      <LabeledField
        label="Zone PLU (libellé ou code)"
        value={pluZone}
        onChangeText={setPluZone}
      />
      <LabeledField
        label="Notes urbanisme (servitude, COS…)"
        value={pluNotes}
        onChangeText={setPluNotes}
        multiline
      />
      <View style={styles.switchRow}>
        <Text style={styles.switchLabel}>Piste division parcellaire</Text>
        <Switch value={parcelDiv} onValueChange={setParcelDiv} />
      </View>
      <View style={styles.switchRow}>
        <Text style={styles.switchLabel}>Piste déficit foncier (passoire)</Text>
        <Switch value={deficitFoncier} onValueChange={setDeficitFoncier} />
      </View>
      <PrimaryButton
        title="Enregistrer les finances"
        onPress={() => {
          onSave({
            title: title.trim(),
            address_line: address.trim() || null,
            city: city.trim() || null,
            postal_code: postal.trim() || null,
            surface_m2: parseNum(surface) || null,
            purchase_price_target: parseNum(purchase) || null,
            resale_price_estimate: parseNum(resale) || null,
            dvf_reference_price_m2: parseNum(dvf) || null,
            works_estimate_total: parseNum(works) || null,
            misc_acquisition_cost: parseNum(miscA) || null,
            misc_sale_cost: parseNum(miscS) || null,
            carrying_months: Math.round(parseNum(carryM) || 6),
            carrying_annual_rate: parseNum(carryR) || 0.05,
            dpe_class: dpe || null,
            plu_zone_code: pluZone.trim() || null,
            plu_notes: pluNotes.trim() || null,
            parcel_subdivision_candidate: parcelDiv,
            deficit_foncier_candidate: deficitFoncier,
          });
        }}
      />
    </ScrollView>
  );
}

function VisiteTab({
  definitions,
  findings,
  onToggle,
  checklistEUR,
  maxPurchase,
}: {
  definitions: VisitFindingDefinitionRow[];
  findings: DossierVisitFindingRow[];
  onToggle: (code: string, checked: boolean) => void;
  checklistEUR: number;
  maxPurchase: number;
}) {
  const insets = useSafeAreaInsets();
  const rows = definitions.map((def) => {
    const f = findings.find((x) => x.finding_code === def.code);
    return { def, f };
  });

  return (
    <ScrollView
      contentContainerStyle={{
        padding: 16,
        paddingBottom: insets.bottom + 24,
      }}
    >
      <View style={styles.card}>
        <Text style={styles.cardTitle}>Anti-erreur visite</Text>
        <Text style={styles.muted}>
          Cochez les points noirs : l’app ajoute les travaux associés et recalcule
          le prix d’achat max pour rester à {(MIN_NET_MARGIN_PCT * 100).toFixed(0)}{' '}
          % de marge nette.
        </Text>
        <Text style={styles.highlight}>
          Travaux checklist : {checklistEUR.toLocaleString('fr-FR')} €
        </Text>
        <Text style={styles.highlight}>
          Prix d’achat max (cible marge) :{' '}
          {maxPurchase.toLocaleString('fr-FR')} €
        </Text>
      </View>
      {rows.map(({ def, f }) => {
        const checked = f?.checked ?? false;
        return (
          <View key={def.code} style={styles.visitRow}>
            <View style={{ flex: 1, paddingRight: 12 }}>
              <Text style={styles.visitLabel}>{def.label}</Text>
              <Text style={styles.muted}>
                +{(f?.works_delta_override_eur ?? def.default_works_delta_eur).toLocaleString('fr-FR')}{' '}
                € si coché
              </Text>
            </View>
            <Switch
              value={checked}
              onValueChange={(v) => onToggle(def.code, v)}
              trackColor={{ true: colors.accent, false: colors.border }}
            />
          </View>
        );
      })}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  root: { flex: 1, backgroundColor: colors.bg },
  center: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 24 },
  muted: { color: colors.textMuted, lineHeight: 20 },
  tabBar: { maxHeight: 52, borderBottomWidth: 1, borderBottomColor: colors.border },
  tabBarInner: { paddingHorizontal: 12, paddingVertical: 10, gap: 8, alignItems: 'center' },
  tabChip: {
    paddingHorizontal: 14,
    paddingVertical: 8,
    borderRadius: 999,
    backgroundColor: colors.bgCard,
    marginRight: 8,
    borderWidth: 1,
    borderColor: colors.border,
  },
  tabChipOn: { borderColor: colors.accent, backgroundColor: '#15233d' },
  tabText: { color: colors.textMuted, fontWeight: '600' },
  tabTextOn: { color: colors.text },
  hero: { borderRadius: 16, padding: 20, marginBottom: 16 },
  heroLabel: { color: colors.textMuted, fontSize: 12, textTransform: 'uppercase' },
  heroScore: { fontSize: 44, fontWeight: '800', color: colors.text, marginVertical: 8 },
  heroSub: { color: colors.textMuted, marginTop: 4 },
  card: {
    backgroundColor: colors.bgCard,
    borderRadius: 14,
    padding: 16,
    borderWidth: 1,
    borderColor: colors.border,
  },
  cardTitle: { color: colors.text, fontSize: 18, fontWeight: '700', marginBottom: 12 },
  row: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 10,
    gap: 12,
  },
  rowLabel: { color: colors.textMuted, flex: 1 },
  rowValue: { color: colors.text, fontWeight: '600' },
  highlight: { color: colors.flash, marginTop: 8, fontWeight: '600' },
  visitRow: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: colors.border,
  },
  visitLabel: { color: colors.text, fontWeight: '600' },
  matchRow: {
    paddingVertical: 10,
    borderBottomWidth: 1,
    borderBottomColor: colors.border,
  },
  matchName: { color: colors.text, fontWeight: '700', fontSize: 16 },
  sectionLabel: {
    color: colors.textMuted,
    fontSize: 12,
    textTransform: 'uppercase',
    letterSpacing: 0.06,
    marginTop: 8,
    marginBottom: 6,
  },
  switchRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 14,
    paddingVertical: 4,
  },
  switchLabel: { color: colors.text, flex: 1, paddingRight: 12 },
});
