/**
 * Formulario de inspección generado dinámicamente desde los `fields` de una
 * plantilla. El esquema exacto de cada campo no está fijado en el contrato, así
 * que el renderer es tolerante: deduce key/label/type de varias formas posibles.
 */
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import React, { useCallback, useEffect, useState } from 'react';
import { ScrollView, StyleSheet, Switch, Text, View } from 'react-native';
import { Template } from '../api/types';
import { getTemplate } from '../db/repositories';
import { createInspection } from '../sync/mutations';
import { RootStackParamList } from '../navigation/types';
import {
  Card,
  ChipSelect,
  COLORS,
  Field,
  PrimaryButton,
  SectionTitle,
} from '../ui/components';

type Props = NativeStackScreenProps<RootStackParamList, 'InspectionForm'>;

interface NormField {
  key: string;
  label: string;
  type: 'text' | 'textarea' | 'number' | 'boolean' | 'select';
  options: string[];
}

function normalizeField(raw: unknown, idx: number): NormField {
  const f = (raw ?? {}) as Record<string, unknown>;
  const key = String(f.key ?? f.name ?? f.id ?? `field_${idx}`);
  const label = String(f.label ?? f.name ?? f.key ?? key);
  let type = String(f.type ?? 'text').toLowerCase();
  if (!['text', 'textarea', 'number', 'boolean', 'select'].includes(type)) {
    if (type === 'checkbox' || type === 'bool') type = 'boolean';
    else if (type === 'dropdown') type = 'select';
    else type = 'text';
  }
  const options = Array.isArray(f.options)
    ? (f.options as unknown[]).map((o) =>
        typeof o === 'string' ? o : String((o as Record<string, unknown>)?.value ?? o),
      )
    : [];
  return { key, label, type: type as NormField['type'], options };
}

const RESULTS = ['pass', 'fail', 'na'] as const;

export function InspectionFormScreen({ route, navigation }: Props) {
  const { featureId, featureName, templateId } = route.params;
  const [template, setTemplate] = useState<Template | null>(null);
  const [values, setValues] = useState<Record<string, unknown>>({});
  const [result, setResult] = useState<(typeof RESULTS)[number] | undefined>();
  const [notes, setNotes] = useState('');
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (templateId != null) void getTemplate(templateId).then(setTemplate);
  }, [templateId]);

  const fields: NormField[] = (template?.fields ?? []).map(normalizeField);

  const setValue = useCallback((key: string, v: unknown) => {
    setValues((prev) => ({ ...prev, [key]: v }));
  }, []);

  const onSubmit = useCallback(async () => {
    setSaving(true);
    try {
      await createInspection({
        feature_id: featureId,
        template_id: templateId,
        data: values,
        result,
        notes: notes.trim() || undefined,
        status: 'completed',
      });
      navigation.goBack();
    } finally {
      setSaving(false);
    }
  }, [featureId, templateId, values, result, notes, navigation]);

  return (
    <ScrollView contentContainerStyle={styles.body}>
      <Text style={styles.subtitle}>{featureName}</Text>
      <Text style={styles.tplName}>{template?.name ?? 'Inspección libre'}</Text>

      {fields.map((f) => {
        if (f.type === 'boolean') {
          return (
            <View key={f.key} style={styles.switchRow}>
              <Text style={styles.switchLabel}>{f.label}</Text>
              <Switch
                value={!!values[f.key]}
                onValueChange={(v) => setValue(f.key, v)}
              />
            </View>
          );
        }
        if (f.type === 'select' && f.options.length) {
          return (
            <ChipSelect
              key={f.key}
              label={f.label}
              value={values[f.key] as string | undefined}
              options={f.options}
              onChange={(v) => setValue(f.key, v)}
            />
          );
        }
        return (
          <Field
            key={f.key}
            label={f.label}
            value={values[f.key] != null ? String(values[f.key]) : ''}
            onChangeText={(t) => setValue(f.key, f.type === 'number' ? Number(t) : t)}
            keyboardType={f.type === 'number' ? 'numeric' : 'default'}
            multiline={f.type === 'textarea'}
          />
        );
      })}

      <SectionTitle>Resultado</SectionTitle>
      <Card style={{ marginBottom: 12 }}>
        <ChipSelect label="" value={result} options={RESULTS} onChange={setResult} />
        <Field
          label="Notas"
          value={notes}
          onChangeText={setNotes}
          placeholder="Observaciones…"
          multiline
        />
      </Card>

      <PrimaryButton title="Guardar inspección" onPress={() => void onSubmit()} loading={saving} />
      <View style={{ height: 8 }} />
      <PrimaryButton title="Cancelar" variant="ghost" onPress={() => navigation.goBack()} />
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  body: { padding: 16 },
  subtitle: { color: COLORS.muted, fontSize: 13 },
  tplName: { fontSize: 18, fontWeight: '700', marginBottom: 12 },
  switchRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingVertical: 10,
  },
  switchLabel: { fontSize: 15, flex: 1 },
});
