import { useEffect, useMemo, useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  Image,
  KeyboardAvoidingView,
  Modal,
  Pressable,
  Platform,
  StyleSheet,
  TextInput,
  View,
} from 'react-native';
import * as ImagePicker from 'expo-image-picker';

import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { IconSymbol } from '@/components/ui/icon-symbol';
import { Colors, Fonts } from '@/constants/theme';
import { useTranslation } from '@/localization/i18n';
import { dbPromise, initCoreTables } from '@/services/db';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { ThemedButton } from '@/components/themed-button';
import { IconButton } from '@/components/icon-button';

type FieldRow = {
  id: number;
  name: string | null;
};

type CropRow = {
  id: number;
  field_id: number | null;
  crop_name: string | null;
};

type ObservationRow = {
  id: number;
  field_id: number | null;
  crop_id: number | null;
  obs_type: string | null;
  note: string | null;
  severity: number | null;
  observed_at: string | null;
  field_name: string | null;
  crop_name: string | null;
  image_uri: string | null;
};

export default function ObservationsScreen() {
  const { t } = useTranslation();
  const theme = useColorScheme() ?? 'light';
  const palette = Colors[theme];
  const presetTypes = [
    { key: 'scouting', value: 'Scouting' },
    { key: 'pest', value: 'Pest' },
    { key: 'disease', value: 'Disease' },
    { key: 'irrigation', value: 'Irrigation' },
    { key: 'weeds', value: 'Weeds' },
    { key: 'nutrients', value: 'Nutrients' },
  ];
  const pageSize = 12;
  const [observations, setObservations] = useState<ObservationRow[]>([]);
  const [fields, setFields] = useState<FieldRow[]>([]);
  const [crops, setCrops] = useState<CropRow[]>([]);
  const [status, setStatus] = useState(t('observations.loading'));
  const [selectedFieldId, setSelectedFieldId] = useState<number | null>(null);
  const [selectedCropId, setSelectedCropId] = useState<number | null>(null);
  const [type, setType] = useState('scouting');
  const [severity, setSeverity] = useState('');
  const [note, setNote] = useState('');
  const [photoUri, setPhotoUri] = useState<string | null>(null);
  const [fieldModalOpen, setFieldModalOpen] = useState(false);
  const [cropModalOpen, setCropModalOpen] = useState(false);
  const [newModalOpen, setNewModalOpen] = useState(false);
  const [reopenSheetAfterSelect, setReopenSheetAfterSelect] = useState(false);
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editFieldId, setEditFieldId] = useState<number | null>(null);
  const [editCropId, setEditCropId] = useState<number | null>(null);
  const [editType, setEditType] = useState('');
  const [editSeverity, setEditSeverity] = useState('');
  const [editNote, setEditNote] = useState('');
  const [editPhotoUri, setEditPhotoUri] = useState<string | null>(null);
  const [editReopenAfterSelect, setEditReopenAfterSelect] = useState(false);
  const [newErrors, setNewErrors] = useState<{ field?: string; severity?: string }>({});
  const [editErrors, setEditErrors] = useState<{ field?: string; severity?: string }>({});
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);

  const selectedField = useMemo(
    () => fields.find((item) => item.id === selectedFieldId),
    [fields, selectedFieldId]
  );
  const selectedCrop = useMemo(
    () => crops.find((item) => item.id === selectedCropId),
    [crops, selectedCropId]
  );
  const selectedEditField = useMemo(
    () => fields.find((item) => item.id === editFieldId),
    [fields, editFieldId]
  );
  const selectedEditCrop = useMemo(
    () => crops.find((item) => item.id === editCropId),
    [crops, editCropId]
  );

  useEffect(() => {
    let isActive = true;

    async function loadData() {
      try {
        await initCoreTables();
        const db = await dbPromise;
        const fieldRows = await db.getAllAsync<FieldRow>(
          'SELECT id, name FROM fields ORDER BY name ASC;'
        );
        const cropRows = await db.getAllAsync<CropRow>(
          'SELECT id, field_id, crop_name FROM crops ORDER BY id DESC;'
        );
        if (!isActive) return;
        setFields(fieldRows);
        setCrops(cropRows);
        await fetchObservationsPage(1, true, isActive);
      } catch (error) {
        if (isActive) setStatus(`Error: ${String(error)}`);
      }
    }

    loadData();
    return () => {
      isActive = false;
    };
  }, [t]);

  async function fetchObservationsPage(
    pageToLoad: number,
    replace: boolean,
    isActive = true
  ) {
    try {
      const db = await dbPromise;
      const observationRows = await db.getAllAsync<ObservationRow>(
        observationQuery,
        pageSize,
        (pageToLoad - 1) * pageSize
      );
      if (!isActive) return;
      setObservations((prev) =>
        replace ? observationRows : [...prev, ...observationRows]
      );
      setHasMore(observationRows.length === pageSize);
      setPage(pageToLoad);
      if (replace) {
        setStatus(observationRows.length === 0 ? t('observations.empty') : '');
      }
    } catch (error) {
      if (isActive) setStatus(`Error: ${String(error)}`);
    } finally {
      if (isActive) setLoadingMore(false);
    }
  }

  async function handleLoadMore() {
    if (loadingMore || !hasMore) return;
    setLoadingMore(true);
    const nextPage = page + 1;
    await fetchObservationsPage(nextPage, false);
  }

  const observationQuery = `
    SELECT o.id, o.field_id, o.crop_id, o.obs_type, o.note, o.severity, o.observed_at,
           f.name as field_name, c.crop_name as crop_name,
           i.uri as image_uri
    FROM observations o
    LEFT JOIN fields f ON f.id = o.field_id
    LEFT JOIN crops c ON c.id = o.crop_id
    LEFT JOIN images i ON i.id = (
      SELECT id FROM images WHERE observation_id = o.id ORDER BY created_at DESC LIMIT 1
    )
    ORDER BY o.observed_at DESC
    LIMIT ? OFFSET ?;`;

  async function handleSave() {
    const parsedSeverity = severity.trim() ? Number(severity) : null;
    const nextErrors: { field?: string; severity?: string } = {};
    if (!selectedFieldId) {
      nextErrors.field = t('observations.fieldRequired');
    }
    if (severity.trim() && !Number.isFinite(parsedSeverity)) {
      nextErrors.severity = t('observations.severityInvalid');
    }
    setNewErrors(nextErrors);
    if (Object.keys(nextErrors).length > 0) {
      setStatus(nextErrors.field ?? nextErrors.severity ?? t('observations.fieldRequired'));
      return false;
    }
    try {
      const db = await dbPromise;
      const now = new Date().toISOString();
      const result = await db.runAsync(
        'INSERT INTO observations (field_id, crop_id, obs_type, note, severity, observed_at) VALUES (?, ?, ?, ?, ?, ?);',
        selectedFieldId,
        selectedCropId,
        type.trim() || null,
        note.trim() || null,
        parsedSeverity,
        now
      );
      const newId = result.lastInsertRowId;
      if (photoUri && newId) {
        await db.runAsync(
          'INSERT INTO images (observation_id, uri, created_at) VALUES (?, ?, ?);',
          newId,
          photoUri,
          now
        );
      }
      setNote('');
      setSeverity('');
      setPhotoUri(null);
      setNewErrors({});
      setStatus(t('observations.saved'));
      await fetchObservationsPage(1, true);
      return true;
    } catch (error) {
      setStatus(`Error: ${String(error)}`);
      return false;
    }
  }

  async function handleDelete(id: number) {
    try {
      const db = await dbPromise;
      await db.runAsync('DELETE FROM images WHERE observation_id = ?;', id);
      await db.runAsync('DELETE FROM observations WHERE id = ?;', id);
      await fetchObservationsPage(1, true);
    } catch (error) {
      setStatus(`Error: ${String(error)}`);
    }
  }

  function startEdit(obs: ObservationRow) {
    setEditingId(obs.id);
    setEditFieldId(obs.field_id ?? null);
    setEditCropId(obs.crop_id ?? null);
    setEditType(obs.obs_type ?? '');
    setEditSeverity(obs.severity !== null ? String(obs.severity) : '');
    setEditNote(obs.note ?? '');
    setEditPhotoUri(obs.image_uri ?? null);
    setEditErrors({});
    setEditModalOpen(true);
  }

  function cancelEdit() {
    setEditingId(null);
    setEditFieldId(null);
    setEditCropId(null);
    setEditType('');
    setEditSeverity('');
    setEditNote('');
    setEditPhotoUri(null);
    setEditErrors({});
    setEditModalOpen(false);
  }

  async function handleUpdate() {
    if (!editingId) return;
    const parsedSeverity = editSeverity.trim() ? Number(editSeverity) : null;
    const nextErrors: { field?: string; severity?: string } = {};
    if (!editFieldId) {
      nextErrors.field = t('observations.fieldRequired');
    }
    if (editSeverity.trim() && !Number.isFinite(parsedSeverity)) {
      nextErrors.severity = t('observations.severityInvalid');
    }
    setEditErrors(nextErrors);
    if (Object.keys(nextErrors).length > 0) {
      setStatus(nextErrors.field ?? nextErrors.severity ?? t('observations.fieldRequired'));
      return;
    }
    try {
      const db = await dbPromise;
      await db.runAsync(
        'UPDATE observations SET field_id = ?, crop_id = ?, obs_type = ?, note = ?, severity = ? WHERE id = ?;',
        editFieldId,
        editCropId,
        editType.trim() || null,
        editNote.trim() || null,
        parsedSeverity,
        editingId
      );
      await db.runAsync('DELETE FROM images WHERE observation_id = ?;', editingId);
      if (editPhotoUri) {
        await db.runAsync(
          'INSERT INTO images (observation_id, uri, created_at) VALUES (?, ?, ?);',
          editingId,
          editPhotoUri,
          new Date().toISOString()
        );
      }
      setEditModalOpen(false);
      setEditingId(null);
      setEditErrors({});
      setStatus(t('observations.saved'));
      await fetchObservationsPage(1, true);
    } catch (error) {
      setStatus(`Error: ${String(error)}`);
    }
  }

  const inputStyle = [
    styles.input,
    { borderColor: palette.border, backgroundColor: palette.input, color: palette.text },
  ];

  return (
    <>
      <FlatList
        data={observations}
        keyExtractor={(item) => String(item.id)}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={0.4}
        renderItem={({ item }) => (
          <Pressable onPress={() => startEdit(item)}>
          <ThemedView style={[styles.card, { backgroundColor: palette.card, borderColor: palette.border }]}>
              <ThemedText type="subtitle">{item.obs_type || t('observations.untitled')}</ThemedText>
              <ThemedText style={styles.meta}>
                {item.field_name || t('observations.noField')} ·{' '}
                {item.crop_name || t('observations.noCrop')}
              </ThemedText>
              {item.severity !== null ? (
                <ThemedText style={styles.meta}>
                  {t('observations.severityLabel')} {item.severity}
                </ThemedText>
              ) : null}
              {item.note ? <ThemedText>{item.note}</ThemedText> : null}
              {item.image_uri ? (
                <Image
                  source={{ uri: item.image_uri }}
                  style={styles.photoPreview}
                  resizeMode="cover"
                />
              ) : null}
              {item.observed_at ? (
                <ThemedText style={styles.meta}>{formatDate(item.observed_at)}</ThemedText>
              ) : null}
              <View style={styles.buttonRow}>
                <IconButton
                  name="trash"
                  onPress={() => handleDelete(item.id)}
                  accessibilityLabel={t('observations.delete')}
                  variant="danger"
                />
              </View>
            </ThemedView>
          </Pressable>
        )}
        ItemSeparatorComponent={() => <View style={styles.separator} />}
        ListHeaderComponent={
          <View>
            <ThemedView style={styles.hero}>
              <Image source={require('@/assets/images/observations.jpg')} style={styles.heroImage} />
            </ThemedView>
            <ThemedView style={styles.titleContainer}>
              <ThemedText type="title" style={{ fontFamily: Fonts.rounded }}>
                {t('observations.title')}
              </ThemedText>
            </ThemedView>

            {status ? (
              <ThemedView style={styles.section}>
                <ThemedText>{status}</ThemedText>
              </ThemedView>
            ) : null}
            <ThemedView style={styles.section}>
              <Pressable
                style={styles.newButton}
                onPress={() => {
                  setNewErrors({});
                  setNewModalOpen(true);
                }}>
                <IconSymbol size={18} name="plus.circle.fill" color="#2F7D4F" />
                <ThemedText style={styles.newButtonText}>{t('observations.new')}</ThemedText>
              </Pressable>
            </ThemedView>
          </View>
        }
        ListFooterComponent={
          <View style={styles.footer}>
            {loadingMore ? <ActivityIndicator /> : null}
          </View>
        }
      />

      <Modal transparent visible={fieldModalOpen} animationType="fade">
        <Pressable
          style={styles.modalOverlay}
          onPress={() => {
            setFieldModalOpen(false);
            setReopenSheetAfterSelect(false);
            setEditReopenAfterSelect(false);
          }}>
          <View style={[styles.modalCard, { backgroundColor: palette.card, borderColor: palette.border }]}>
            <ThemedText type="subtitle">{t('observations.selectField')}</ThemedText>
            <FlatList
              data={fields}
              keyExtractor={(item) => String(item.id)}
              renderItem={({ item }) => (
                <Pressable
                  onPress={() => {
                    if (editReopenAfterSelect) {
                      setEditFieldId(item.id);
                      setEditCropId(null);
                      setEditErrors((prev) => ({ ...prev, field: undefined }));
                      setEditModalOpen(true);
                      setEditReopenAfterSelect(false);
                    } else {
                      setSelectedFieldId(item.id);
                      setSelectedCropId(null);
                      setNewErrors((prev) => ({ ...prev, field: undefined }));
                      setNewModalOpen(true);
                      setReopenSheetAfterSelect(false);
                    }
                    setFieldModalOpen(false);
                  }}
                  style={styles.modalItem}>
                  <ThemedText>{item.name || t('observations.untitled')}</ThemedText>
                </Pressable>
              )}
            />
          </View>
        </Pressable>
      </Modal>

      <Modal transparent visible={cropModalOpen} animationType="fade">
        <Pressable
          style={styles.modalOverlay}
          onPress={() => {
            setCropModalOpen(false);
            setReopenSheetAfterSelect(false);
            setEditReopenAfterSelect(false);
          }}>
          <View style={[styles.modalCard, { backgroundColor: palette.card, borderColor: palette.border }]}>
            <ThemedText type="subtitle">{t('observations.selectCrop')}</ThemedText>
            <FlatList
              data={crops.filter((item) => !selectedFieldId || item.field_id === selectedFieldId)}
              keyExtractor={(item) => String(item.id)}
              renderItem={({ item }) => (
                <Pressable
                  onPress={() => {
                    if (editReopenAfterSelect) {
                      setEditCropId(item.id);
                      setEditModalOpen(true);
                      setEditReopenAfterSelect(false);
                    } else {
                      setSelectedCropId(item.id);
                      setNewModalOpen(true);
                      setReopenSheetAfterSelect(false);
                    }
                    setCropModalOpen(false);
                  }}
                  style={styles.modalItem}>
                  <ThemedText>{item.crop_name || t('observations.untitled')}</ThemedText>
                </Pressable>
              )}
              ListEmptyComponent={
                <ThemedText style={styles.meta}>{t('observations.noCrop')}</ThemedText>
              }
            />
          </View>
        </Pressable>
      </Modal>

      <Modal transparent visible={newModalOpen} animationType="slide">
        <View style={styles.sheetOverlay}>
          <Pressable style={styles.sheetBackdrop} onPress={() => setNewModalOpen(false)} />
          <KeyboardAvoidingView
            behavior={Platform.OS === 'ios' ? 'padding' : undefined}
            keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
            style={styles.keyboardAvoid}>
            <View style={[styles.sheet, { backgroundColor: palette.card, borderColor: palette.border }]}>
              <FlatList
                data={[{ key: 'new' }]}
                keyExtractor={(item) => item.key}
                contentContainerStyle={styles.sheetListContent}
                renderItem={() => (
                  <View style={styles.sheetContent}>
                  <ThemedText type="subtitle">{t('observations.new')}</ThemedText>
                  <ThemedText>
                    {t('observations.field')}
                    <ThemedText style={styles.requiredMark}> *</ThemedText>
                  </ThemedText>
                  <ThemedButton
                    title={selectedField?.name || t('observations.selectField')}
                    onPress={() => {
                      setReopenSheetAfterSelect(true);
                      setNewModalOpen(false);
                      setFieldModalOpen(true);
                    }}
                    variant="secondary"
                  />
                  {newErrors.field ? (
                    <ThemedText style={styles.errorText}>{newErrors.field}</ThemedText>
                  ) : null}
                  <ThemedText>{t('observations.crop')}</ThemedText>
                  <ThemedButton
                    title={selectedCrop?.crop_name || t('observations.selectCrop')}
                    onPress={() => {
                      setReopenSheetAfterSelect(true);
                      setNewModalOpen(false);
                      setCropModalOpen(true);
                    }}
                    variant="secondary"
                  />
                  <ThemedText>{t('observations.type')}</ThemedText>
                  <View style={styles.chipRow}>
                    {presetTypes.map((preset) => {
                      const label = t(`observations.type.${preset.key}`);
                      const normalized = type.trim().toLowerCase();
                      const isActive =
                        label.toLowerCase() === normalized ||
                        preset.value.toLowerCase() === normalized;
                      return (
                        <Pressable
                          key={preset.key}
                          onPress={() => setType(label)}
                          style={[styles.chip, isActive && styles.chipActive]}>
                          <ThemedText style={isActive ? styles.chipTextActive : styles.chipText}>
                            {label}
                          </ThemedText>
                        </Pressable>
                      );
                    })}
                  </View>
                  <TextInput
                    value={type}
                    onChangeText={setType}
                    placeholder={t('observations.typePlaceholder')}
                    style={inputStyle}
                  />
                  <ThemedText>{t('observations.severity')}</ThemedText>
                  <TextInput
                    value={severity}
                    onChangeText={(value) => {
                      setSeverity(value);
                      if (newErrors.severity) {
                        setNewErrors((prev) => ({ ...prev, severity: undefined }));
                      }
                    }}
                    placeholder={t('observations.severityPlaceholder')}
                    style={inputStyle}
                    keyboardType="numeric"
                  />
                  {newErrors.severity ? (
                    <ThemedText style={styles.errorText}>{newErrors.severity}</ThemedText>
                  ) : null}
                  <ThemedText>{t('observations.note')}</ThemedText>
                  <TextInput
                    value={note}
                    onChangeText={setNote}
                    placeholder={t('observations.notePlaceholder')}
                    style={inputStyle}
                    multiline
                  />
                  <ThemedText>{t('observations.photo')}</ThemedText>
                  {photoUri ? (
                    <Image source={{ uri: photoUri }} style={styles.photoPreview} resizeMode="cover" />
                  ) : (
                    <ThemedText style={styles.photoPlaceholder}>{t('observations.noPhoto')}</ThemedText>
                  )}
                  <View style={styles.photoRow}>
                    <ThemedButton
                      title={t('observations.pickPhoto')}
                      onPress={() => handlePickPhoto(setPhotoUri)}
                      variant="secondary"
                    />
                    <ThemedButton
                      title={t('observations.takePhoto')}
                      onPress={() =>
                        handleTakePhoto(setPhotoUri, (code) =>
                          setStatus(
                            code === 'cameraDenied'
                              ? t('tasks.cameraDenied')
                              : t('tasks.cameraError')
                          )
                        )
                      }
                      variant="secondary"
                    />
                  </View>
                  <View style={styles.modalActions}>
                    <ThemedButton
                      title={t('observations.cancel')}
                      onPress={() => setNewModalOpen(false)}
                      variant="secondary"
                    />
                    <ThemedButton
                      title={t('observations.save')}
                      onPress={async () => {
                        const ok = await handleSave();
                        if (ok) setNewModalOpen(false);
                      }}
                    />
                  </View>
                  <View style={styles.sheetFooter} />
                </View>
                )}
              />
            </View>
          </KeyboardAvoidingView>
        </View>
      </Modal>

      <Modal transparent visible={editModalOpen} animationType="slide">
        <View style={styles.sheetOverlay}>
          <Pressable style={styles.sheetBackdrop} onPress={cancelEdit} />
          <KeyboardAvoidingView
            behavior={Platform.OS === 'ios' ? 'padding' : undefined}
            keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
            style={styles.keyboardAvoid}>
            <View style={[styles.sheet, { backgroundColor: palette.card, borderColor: palette.border }]}>
              <FlatList
                data={[{ key: 'edit' }]}
                keyExtractor={(item) => item.key}
                contentContainerStyle={styles.sheetListContent}
                renderItem={() => (
                  <View style={styles.sheetContent}>
                  <ThemedText type="subtitle">{t('observations.edit')}</ThemedText>
                  <ThemedText>
                    {t('observations.field')}
                    <ThemedText style={styles.requiredMark}> *</ThemedText>
                  </ThemedText>
                  <ThemedButton
                    title={selectedEditField?.name || t('observations.selectField')}
                    onPress={() => {
                      setEditReopenAfterSelect(true);
                      setEditModalOpen(false);
                      setFieldModalOpen(true);
                    }}
                    variant="secondary"
                  />
                  {editErrors.field ? (
                    <ThemedText style={styles.errorText}>{editErrors.field}</ThemedText>
                  ) : null}
                  <ThemedText>{t('observations.crop')}</ThemedText>
                  <ThemedButton
                    title={selectedEditCrop?.crop_name || t('observations.selectCrop')}
                    onPress={() => {
                      setEditReopenAfterSelect(true);
                      setEditModalOpen(false);
                      setCropModalOpen(true);
                    }}
                    variant="secondary"
                  />
                  <ThemedText>{t('observations.type')}</ThemedText>
                  <View style={styles.chipRow}>
                    {presetTypes.map((preset) => {
                      const label = t(`observations.type.${preset.key}`);
                      const normalized = editType.trim().toLowerCase();
                      const isActive =
                        label.toLowerCase() === normalized ||
                        preset.value.toLowerCase() === normalized;
                      return (
                        <Pressable
                          key={`edit-${preset.key}`}
                          onPress={() => setEditType(label)}
                          style={[styles.chip, isActive && styles.chipActive]}>
                          <ThemedText style={isActive ? styles.chipTextActive : styles.chipText}>
                            {label}
                          </ThemedText>
                        </Pressable>
                      );
                    })}
                  </View>
                  <TextInput
                    value={editType}
                    onChangeText={setEditType}
                    placeholder={t('observations.typePlaceholder')}
                    style={inputStyle}
                  />
                  <ThemedText>{t('observations.severity')}</ThemedText>
                  <TextInput
                    value={editSeverity}
                    onChangeText={(value) => {
                      setEditSeverity(value);
                      if (editErrors.severity) {
                        setEditErrors((prev) => ({ ...prev, severity: undefined }));
                      }
                    }}
                    placeholder={t('observations.severityPlaceholder')}
                    style={inputStyle}
                    keyboardType="numeric"
                  />
                  {editErrors.severity ? (
                    <ThemedText style={styles.errorText}>{editErrors.severity}</ThemedText>
                  ) : null}
                  <ThemedText>{t('observations.note')}</ThemedText>
                  <TextInput
                    value={editNote}
                    onChangeText={setEditNote}
                    placeholder={t('observations.notePlaceholder')}
                    style={inputStyle}
                    multiline
                  />
                  <ThemedText>{t('observations.photo')}</ThemedText>
                  {editPhotoUri ? (
                    <Image
                      source={{ uri: editPhotoUri }}
                      style={styles.photoPreview}
                      resizeMode="cover"
                    />
                  ) : (
                    <ThemedText style={styles.photoPlaceholder}>
                      {t('observations.noPhoto')}
                    </ThemedText>
                  )}
                  <View style={styles.photoRow}>
                    <ThemedButton
                      title={t('observations.pickPhoto')}
                      onPress={() => handlePickPhoto(setEditPhotoUri)}
                      variant="secondary"
                    />
                    <ThemedButton
                      title={t('observations.takePhoto')}
                      onPress={() =>
                        handleTakePhoto(setEditPhotoUri, (code) =>
                          setStatus(
                            code === 'cameraDenied'
                              ? t('tasks.cameraDenied')
                              : t('tasks.cameraError')
                          )
                        )
                      }
                      variant="secondary"
                    />
                  </View>
                  <View style={styles.modalActions}>
                    <ThemedButton
                      title={t('observations.cancel')}
                      onPress={cancelEdit}
                      variant="secondary"
                    />
                    <ThemedButton title={t('observations.update')} onPress={handleUpdate} />
                  </View>
                  <View style={styles.sheetFooter} />
                </View>
                )}
              />
            </View>
          </KeyboardAvoidingView>
        </View>
      </Modal>
    </>
  );
}

function formatDate(value: string) {
  try {
    return new Date(value).toLocaleString();
  } catch {
    return value;
  }
}

async function handlePickPhoto(setter: (value: string | null) => void) {
  const result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: getImageMediaTypes(),
    quality: 1,
  });
  if (result.canceled) return;
  const asset = result.assets[0];
  console.log('[Observations] Picked photo:', asset.uri);
  setter(asset.uri);
}

async function handleTakePhoto(
  setter: (value: string | null) => void,
  onError?: (msg: string) => void
) {
  try {
    const permission = await ImagePicker.requestCameraPermissionsAsync();
    if (!permission.granted) {
      onError?.('cameraDenied');
      return;
    }
    const result = await ImagePicker.launchCameraAsync({ quality: 1 });
    if (result.canceled) return;
    const asset = result.assets[0];
    console.log('[Observations] Captured photo:', asset.uri);
    setter(asset.uri);
  } catch {
    onError?.('cameraError');
  }
}

function getImageMediaTypes() {
  const mediaType = (ImagePicker as { MediaType?: { Image?: unknown; Images?: unknown } })
    .MediaType;
  return mediaType?.Image ?? mediaType?.Images ?? ['images'];
}

const styles = StyleSheet.create({
  hero: {
    backgroundColor: '#E8E6DA',
    aspectRatio: 16 / 9,
    width: '100%',
  },
  heroImage: {
    width: '100%',
    height: '100%',
  },
  titleContainer: {
    gap: 8,
    paddingHorizontal: 16,
    paddingVertical: 12,
  },
  section: {
    gap: 8,
    marginBottom: 16,
    paddingHorizontal: 16,
  },
  card: {
    borderRadius: 12,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    padding: 12,
    marginHorizontal: 16,
    gap: 6,
    backgroundColor: '#FFFFFF',
  },
  meta: {
    opacity: 0.7,
  },
  input: {
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#B9B9B9',
    paddingHorizontal: 12,
    paddingVertical: 10,
    fontSize: 15,
  },
  requiredMark: {
    color: '#C0392B',
    fontWeight: '700',
  },
  errorText: {
    color: '#C0392B',
    fontSize: 12,
  },
  buttonRow: {
    alignSelf: 'flex-start',
  },
  separator: {
    height: 12,
  },
  footer: {
    height: 24,
  },
  modalOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.3)',
    justifyContent: 'center',
    padding: 16,
  },
  modalCard: {
    borderRadius: 12,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    padding: 16,
    backgroundColor: '#FFFFFF',
    gap: 8,
    maxHeight: '70%',
  },
  modalItem: {
    paddingVertical: 8,
  },
  newButton: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#B9B9B9',
    paddingHorizontal: 12,
    paddingVertical: 10,
    alignSelf: 'flex-start',
  },
  newButtonText: {
    fontSize: 15,
    fontWeight: '600',
  },
  modalActions: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    gap: 12,
  },
  chipRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
  },
  chip: {
    borderRadius: 999,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    paddingHorizontal: 12,
    paddingVertical: 6,
  },
  chipActive: {
    borderColor: '#2F7D4F',
    backgroundColor: '#E7F3EA',
  },
  chipText: {
    fontSize: 13,
  },
  chipTextActive: {
    fontSize: 13,
    color: '#2F7D4F',
    fontWeight: '600',
  },
  photoRow: {
    flexDirection: 'row',
    gap: 12,
  },
  photoPlaceholder: {
    opacity: 0.6,
  },
  photoPreview: {
    width: '100%',
    height: 160,
    borderRadius: 12,
  },
  sheetOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.3)',
    justifyContent: 'flex-end',
  },
  sheetBackdrop: {
    ...StyleSheet.absoluteFillObject,
  },
  sheet: {
    borderTopLeftRadius: 16,
    borderTopRightRadius: 16,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    padding: 16,
    backgroundColor: '#FFFFFF',
    gap: 10,
    maxHeight: '85%',
  },
  sheetContent: {
    gap: 10,
    paddingBottom: 8,
  },
  sheetListContent: {
    paddingBottom: 80,
  },
  sheetFooter: {
    height: 24,
  },
  keyboardAvoid: {
    width: '100%',
    flex: 1,
    justifyContent: 'flex-end',
  },
});
