import { useEffect, useMemo, useState } from 'react';
import {
  Image,
  KeyboardAvoidingView,
  Modal,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  TextInput,
  View,
} from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import DateTimePicker from '@react-native-community/datetimepicker';
import { ResizeMode, Video } from 'expo-av';
import { useRouter } from 'expo-router';

import { ThemedButton } from '@/components/themed-button';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { ZoomImageModal } from '@/components/zoom-image-modal';
import { Colors } from '@/constants/theme';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { useTranslation } from '@/localization/i18n';
import { dbPromise, initCoreTables } from '@/services/db';

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

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

export default function NewHarvestScreen() {
  const { t } = useTranslation();
  const router = useRouter();
  const theme = useColorScheme() ?? 'light';
  const palette = Colors[theme];

  const [status, setStatus] = useState('');
  const [fields, setFields] = useState<FieldRow[]>([]);
  const [crops, setCrops] = useState<CropRow[]>([]);
  const [fieldModalOpen, setFieldModalOpen] = useState(false);
  const [cropModalOpen, setCropModalOpen] = useState(false);
  const [selectedFieldId, setSelectedFieldId] = useState<number | null>(null);
  const [selectedCropId, setSelectedCropId] = useState<number | null>(null);
  const [harvestDate, setHarvestDate] = useState('');
  const [showHarvestPicker, setShowHarvestPicker] = useState(false);
  const [quantity, setQuantity] = useState('');
  const [unit, setUnit] = useState('');
  const [notes, setNotes] = useState('');
  const [mediaUris, setMediaUris] = useState<string[]>([]);
  const [activeUri, setActiveUri] = useState<string | null>(null);
  const [errors, setErrors] = useState<{ field?: string; crop?: string; quantity?: string }>({});
  const [zoomUri, setZoomUri] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const unitPresets = [
    { key: 'kg', label: 'kg' },
    { key: 'g', label: 'g' },
    { key: 'ton', label: 'ton' },
    { key: 'pcs', label: 'pcs' },
  ];

  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, crop_name FROM crops ORDER BY crop_name ASC;');
        if (!isActive) return;
        setFields(fieldRows);
        setCrops(cropRows);
      } catch (error) {
        if (isActive) setStatus(`Error: ${String(error)}`);
      }
    }

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

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

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

  async function handleSave() {
    const parsedQuantity = quantity.trim() ? Number(quantity) : null;
    const nextErrors: { field?: string; crop?: string; quantity?: string } = {};
    if (!selectedFieldId) nextErrors.field = t('harvests.fieldRequired');
    if (!selectedCropId) nextErrors.crop = t('harvests.cropRequired');
    if (quantity.trim() && !Number.isFinite(parsedQuantity)) {
      nextErrors.quantity = t('harvests.quantityInvalid');
    }
    setErrors(nextErrors);
    if (Object.keys(nextErrors).length > 0) return;
    try {
      setSaving(true);
      const db = await dbPromise;
      const now = new Date().toISOString();
      const primaryUri = mediaUris[0] ?? normalizeMediaUri(activeUri);
      const result = await db.runAsync(
        'INSERT INTO harvests (field_id, crop_id, harvested_at, quantity, unit, notes, photo_uri, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?);',
        selectedFieldId,
        selectedCropId,
        harvestDate || null,
        parsedQuantity,
        unit.trim() || null,
        notes.trim() || null,
        primaryUri ?? null,
        now
      );
      const harvestId = Number(result.lastInsertRowId);
      if (harvestId) {
        const mediaToInsert = uniqueMediaUris([
          ...mediaUris,
          ...(normalizeMediaUri(activeUri) ? [normalizeMediaUri(activeUri) as string] : []),
        ]);
        for (const uri of mediaToInsert) {
          await db.runAsync(
            'INSERT INTO harvest_media (harvest_id, uri, media_type, created_at) VALUES (?, ?, ?, ?);',
            harvestId,
            uri,
            isVideoUri(uri) ? 'video' : 'image',
            now
          );
        }
      }
      setStatus(t('harvests.saved'));
      router.back();
    } catch (error) {
      setStatus(`Error: ${String(error)}`);
    } finally {
      setSaving(false);
    }
  }

  return (
    <ThemedView style={[styles.container, { backgroundColor: palette.background }]}>
      <KeyboardAvoidingView
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        style={styles.keyboardAvoid}>
        <ScrollView contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled">
          <ThemedText type="title">{t('harvests.new')}</ThemedText>
          {status ? <ThemedText>{status}</ThemedText> : null}

          <ThemedText>{t('harvests.field')}</ThemedText>
          <ThemedButton
            title={selectedField?.name || t('harvests.selectField')}
            onPress={() => setFieldModalOpen(true)}
            variant="secondary"
          />
          {errors.field ? <ThemedText style={styles.errorText}>{errors.field}</ThemedText> : null}

          <ThemedText>{t('harvests.crop')}</ThemedText>
          <ThemedButton
            title={selectedCrop?.crop_name || t('harvests.selectCrop')}
            onPress={() => setCropModalOpen(true)}
            variant="secondary"
          />
          {errors.crop ? <ThemedText style={styles.errorText}>{errors.crop}</ThemedText> : null}

          <ThemedText>{t('harvests.date')}</ThemedText>
          <Pressable onPress={() => setShowHarvestPicker(true)} style={styles.dateInput}>
            <ThemedText style={styles.dateValue}>
              {harvestDate || t('harvests.datePlaceholder')}
            </ThemedText>
          </Pressable>
          {showHarvestPicker ? (
            <DateTimePicker
              value={harvestDate ? new Date(harvestDate) : new Date()}
              mode="date"
              onChange={(event, date) => {
                setShowHarvestPicker(false);
                if (date) setHarvestDate(toDateOnly(date));
              }}
            />
          ) : null}

          <ThemedText>{t('harvests.quantity')}</ThemedText>
          <TextInput
            value={quantity}
            onChangeText={(value) => {
              setQuantity(value);
              if (errors.quantity) setErrors((prev) => ({ ...prev, quantity: undefined }));
            }}
            placeholder={t('harvests.quantityPlaceholder')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
            keyboardType="decimal-pad"
          />
          {errors.quantity ? <ThemedText style={styles.errorText}>{errors.quantity}</ThemedText> : null}

          <ThemedText>{t('harvests.unit')}</ThemedText>
          <View style={styles.unitRow}>
            {unitPresets.map((preset) => {
              const label = t(`units.${preset.key}`);
              const isActive = unit === label || unit === preset.key;
              return (
                <Pressable
                  key={`unit-${preset.key}`}
                  onPress={() => setUnit(label)}
                  style={[styles.unitChip, isActive ? styles.unitChipActive : null]}>
                  <ThemedText style={isActive ? styles.unitTextActive : styles.unitText}>{label}</ThemedText>
                </Pressable>
              );
            })}
          </View>
          <TextInput
            value={unit}
            onChangeText={setUnit}
            placeholder={t('harvests.unitPlaceholder')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
          />

          <ThemedText>{t('harvests.notes')}</ThemedText>
          <TextInput
            value={notes}
            onChangeText={setNotes}
            placeholder={t('harvests.notesPlaceholder')}
            placeholderTextColor={palette.placeholder}
            style={inputStyle}
            multiline
          />

          <ThemedText>{t('harvests.addMedia')}</ThemedText>
          {normalizeMediaUri(activeUri) ? (
            isVideoUri(normalizeMediaUri(activeUri) as string) ? (
              <Video
                source={{ uri: normalizeMediaUri(activeUri) as string }}
                style={styles.mediaPreview}
                useNativeControls
                resizeMode={ResizeMode.CONTAIN}
              />
            ) : (
              <Pressable onPress={() => setZoomUri(normalizeMediaUri(activeUri) as string)}>
                <Image source={{ uri: normalizeMediaUri(activeUri) as string }} style={styles.mediaPreview} resizeMode="contain" />
              </Pressable>
            )
          ) : (
            <ThemedText style={styles.photoPlaceholder}>{t('harvests.noPhoto')}</ThemedText>
          )}

          {mediaUris.length > 0 ? (
            <ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.mediaStrip}>
              {mediaUris.map((uri) => (
                <Pressable key={uri} style={styles.mediaChip} onPress={() => setActiveUri(uri)}>
                  {isVideoUri(uri) ? (
                    <View style={styles.videoThumb}>
                      <ThemedText style={styles.videoThumbText}>▶</ThemedText>
                    </View>
                  ) : (
                    <Image source={{ uri }} style={styles.mediaThumb} resizeMode="cover" />
                  )}
                  <Pressable
                    style={styles.mediaRemove}
                    onPress={(event) => {
                      event.stopPropagation();
                      setMediaUris((prev) => {
                        const next = prev.filter((item) => item !== uri);
                        setActiveUri((current) => (current === uri ? next[0] ?? null : current));
                        return next;
                      });
                    }}>
                    <ThemedText style={styles.mediaRemoveText}>×</ThemedText>
                  </Pressable>
                </Pressable>
              ))}
            </ScrollView>
          ) : null}

          <View style={styles.photoRow}>
            <ThemedButton
              title={t('harvests.pickFromGallery')}
              onPress={() =>
                handlePickMedia((uris) => {
                  if (uris.length === 0) return;
                  setMediaUris((prev) => uniqueMediaUris([...prev, ...uris]));
                  setActiveUri((prev) => prev ?? uris[0]);
                })
              }
              variant="secondary"
            />
            <ThemedButton
              title={t('harvests.takeMedia')}
              onPress={() =>
                handleTakeMedia((uri) => {
                  if (!uri) return;
                  setMediaUris((prev) => uniqueMediaUris([...prev, uri]));
                  setActiveUri((prev) => prev ?? uri);
                })
              }
              variant="secondary"
            />
          </View>

          <View style={styles.actions}>
            <ThemedButton
              title={saving ? t('harvests.saving') : t('harvests.save')}
              onPress={handleSave}
              disabled={saving}
            />
          </View>
        </ScrollView>
      </KeyboardAvoidingView>

      <Modal transparent visible={fieldModalOpen} animationType="fade">
        <Pressable style={styles.modalBackdrop} onPress={() => setFieldModalOpen(false)}>
          <View style={styles.modalCard}>
            <ThemedText type="subtitle">{t('harvests.selectField')}</ThemedText>
            <ScrollView style={styles.modalList}>
              {fields.map((item) => (
                <Pressable
                  key={item.id}
                  style={styles.modalItem}
                  onPress={() => {
                    setSelectedFieldId(item.id);
                    setFieldModalOpen(false);
                  }}>
                  <ThemedText>{item.name || t('harvests.noField')}</ThemedText>
                </Pressable>
              ))}
            </ScrollView>
          </View>
        </Pressable>
      </Modal>

      <Modal transparent visible={cropModalOpen} animationType="fade">
        <Pressable style={styles.modalBackdrop} onPress={() => setCropModalOpen(false)}>
          <View style={styles.modalCard}>
            <ThemedText type="subtitle">{t('harvests.selectCrop')}</ThemedText>
            <ScrollView style={styles.modalList}>
              {crops.map((item) => (
                <Pressable
                  key={item.id}
                  style={styles.modalItem}
                  onPress={() => {
                    setSelectedCropId(item.id);
                    setCropModalOpen(false);
                  }}>
                  <ThemedText>{item.crop_name || t('harvests.noCrop')}</ThemedText>
                </Pressable>
              ))}
            </ScrollView>
          </View>
        </Pressable>
      </Modal>

      <ZoomImageModal uri={zoomUri} visible={Boolean(zoomUri)} onClose={() => setZoomUri(null)} />
    </ThemedView>
  );
}

async function handlePickMedia(onAdd: (uris: string[]) => void) {
  const result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: getMediaTypes(),
    quality: 1,
    allowsMultipleSelection: true,
    selectionLimit: 0,
  });
  if (result.canceled) return;
  const uris = (result.assets ?? []).map((asset) => asset.uri).filter(Boolean) as string[];
  if (uris.length === 0) return;
  onAdd(uris);
}

async function handleTakeMedia(onAdd: (uri: string | null) => void) {
  const permission = await ImagePicker.requestCameraPermissionsAsync();
  if (!permission.granted) {
    return;
  }
  const result = await ImagePicker.launchCameraAsync({
    mediaTypes: getMediaTypes(),
    quality: 1,
  });
  if (result.canceled) return;
  const asset = result.assets[0];
  onAdd(asset.uri);
}

function getMediaTypes() {
  const mediaType = (ImagePicker as {
    MediaType?: { Image?: unknown; Images?: unknown; Video?: unknown; Videos?: unknown };
  }).MediaType;
  const imageType = mediaType?.Image ?? mediaType?.Images;
  const videoType = mediaType?.Video ?? mediaType?.Videos;
  if (imageType && videoType) {
    return [imageType, videoType];
  }
  return imageType ?? videoType ?? ['images', 'videos'];
}

function isVideoUri(uri: string) {
  return /\.(mp4|mov|m4v|webm|avi|mkv)(\?.*)?$/i.test(uri);
}

function normalizeMediaUri(uri?: string | null) {
  if (typeof uri !== 'string') return null;
  const trimmed = uri.trim();
  return trimmed ? trimmed : null;
}

function uniqueMediaUris(uris: string[]) {
  const seen = new Set<string>();
  const result: string[] = [];
  for (const uri of uris) {
    if (!uri || seen.has(uri)) continue;
    seen.add(uri);
    result.push(uri);
  }
  return result;
}

function toDateOnly(date: Date) {
  return date.toISOString().slice(0, 10);
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  keyboardAvoid: {
    flex: 1,
  },
  content: {
    padding: 16,
    gap: 10,
    paddingBottom: 40,
  },
  input: {
    borderRadius: 10,
    borderWidth: 1,
    paddingHorizontal: 12,
    paddingVertical: 10,
    fontSize: 15,
  },
  errorText: {
    color: '#C0392B',
    fontSize: 12,
  },
  dateInput: {
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#B9B9B9',
    paddingHorizontal: 12,
    paddingVertical: 10,
  },
  dateValue: {
    opacity: 0.7,
  },
  mediaPreview: {
    width: '100%',
    height: 220,
    borderRadius: 12,
    backgroundColor: '#1C1C1C',
  },
  photoRow: {
    flexDirection: 'row',
    gap: 8,
  },
  actions: {
    marginTop: 12,
    gap: 10,
  },
  photoPlaceholder: {
    opacity: 0.6,
  },
  unitRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
    marginBottom: 8,
  },
  unitChip: {
    borderRadius: 999,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    paddingHorizontal: 10,
    paddingVertical: 4,
  },
  unitChipActive: {
    borderColor: '#2F7D4F',
    backgroundColor: '#E7F3EA',
  },
  unitText: {
    fontSize: 12,
  },
  unitTextActive: {
    fontSize: 12,
    color: '#2F7D4F',
    fontWeight: '600',
  },
  mediaStrip: {
    marginTop: 6,
  },
  mediaChip: {
    width: 72,
    height: 72,
    borderRadius: 10,
    marginRight: 8,
    overflow: 'hidden',
    backgroundColor: '#E6E1D4',
    alignItems: 'center',
    justifyContent: 'center',
  },
  mediaThumb: {
    width: '100%',
    height: '100%',
  },
  videoThumb: {
    width: '100%',
    height: '100%',
    backgroundColor: '#1C1C1C',
    alignItems: 'center',
    justifyContent: 'center',
  },
  videoThumbText: {
    color: '#FFFFFF',
    fontSize: 18,
    fontWeight: '700',
  },
  mediaRemove: {
    position: 'absolute',
    top: 4,
    right: 4,
    width: 18,
    height: 18,
    borderRadius: 9,
    backgroundColor: 'rgba(0,0,0,0.6)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  mediaRemoveText: {
    color: '#FFFFFF',
    fontSize: 12,
    lineHeight: 14,
    fontWeight: '700',
  },
  modalBackdrop: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.4)',
    justifyContent: 'center',
    padding: 24,
  },
  modalCard: {
    borderRadius: 14,
    backgroundColor: '#FFFFFF',
    padding: 16,
    gap: 10,
    maxHeight: '80%',
  },
  modalList: {
    maxHeight: 300,
  },
  modalItem: {
    paddingVertical: 10,
  },
});
