import { useCallback, useEffect, useMemo, useState } from 'react';
import { ActivityIndicator, Pressable, RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native';
import { router, useLocalSearchParams } from 'expo-router';
import * as DocumentPicker from 'expo-document-picker';
import * as ImagePicker from 'expo-image-picker';
import * as WebBrowser from 'expo-web-browser';

import { fetchPlantById, fetchPlantFiles, Plant, ProjectFile, uploadPlantFile } from '@/src/lib/api';
import { useAuth } from '@/src/providers/auth-provider';

const PRIMARY = '#69c350';

function formatDateTime(value: unknown): string {
  if (!value) return '-';
  const date = new Date(String(value));
  if (Number.isNaN(date.getTime())) return String(value);
  return date.toLocaleString('de-DE', {
    day: '2-digit',
    month: '2-digit',
    year: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function getCustomerName(raw: Plant['customer']): string {
  if (!raw) return '-';
  if (typeof raw === 'object') return String(raw.name || raw.id || '-');
  return String(raw);
}

export default function PlantDetailScreen() {
  const params = useLocalSearchParams<{ id?: string }>();
  const plantId = Number(params.id);
  const { token } = useAuth();

  const [plant, setPlant] = useState<Plant | null>(null);
  const [files, setFiles] = useState<ProjectFile[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const validId = useMemo(() => Number.isFinite(plantId) && plantId > 0, [plantId]);

  const rows = useMemo(() => {
    if (!plant) return [];
    return [
      { label: 'Name', value: String(plant.name || '-') },
      { label: 'Kunde', value: getCustomerName(plant.customer) },
      { label: 'Typ', value: String(plant.type || '-') },
      { label: 'Stadt', value: String(plant.city || '-') },
      { label: 'Strasse', value: String(plant.street || '-') },
      { label: 'PLZ', value: String(plant.zip || '-') },
      { label: 'Erstellt', value: formatDateTime(plant.createdAt || plant.created_at) },
      { label: 'Aktualisiert', value: formatDateTime(plant.updatedAt || plant.updated_at) },
    ];
  }, [plant]);

  const load = useCallback(async (showSpinner = true) => {
    if (!token || !validId) return;
    if (showSpinner) setLoading(true);
    setError(null);

    try {
      const [plantData, fileData] = await Promise.all([
        fetchPlantById(token, plantId),
        fetchPlantFiles(token, plantId),
      ]);
      setPlant(plantData);
      setFiles(fileData);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Objektdaten konnten nicht geladen werden.');
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, [plantId, token, validId]);

  useEffect(() => {
    if (!token || !validId) return;
    void load(true);
  }, [load, token, validId]);

  async function onRefresh() {
    setRefreshing(true);
    await load(false);
  }

  async function onOpenFile(file: ProjectFile) {
    if (!file.url) return;
    await WebBrowser.openBrowserAsync(file.url, {
      presentationStyle: WebBrowser.WebBrowserPresentationStyle.FORM_SHEET,
      controlsColor: PRIMARY,
      showTitle: true,
      enableDefaultShareMenuItem: true,
    });
  }

  async function onPickAndUpload() {
    if (!token || !validId || uploading) return;

    const result = await DocumentPicker.getDocumentAsync({
      multiple: false,
      copyToCacheDirectory: true,
      type: ['image/*', 'application/pdf', '*/*'],
    });
    if (result.canceled || !result.assets?.length) return;

    const asset = result.assets[0];
    const filename = asset.name || `upload-${Date.now()}`;
    setUploading(true);
    setError(null);

    try {
      await uploadPlantFile(token, {
        plantId,
        uri: asset.uri,
        filename,
        mimeType: asset.mimeType || 'application/octet-stream',
      });
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen.');
    } finally {
      setUploading(false);
    }
  }

  async function uploadImageFromUri(uri: string, filename: string, mimeType?: string) {
    if (!token || !validId) return;

    setUploading(true);
    setError(null);

    try {
      await uploadPlantFile(token, {
        plantId,
        uri,
        filename,
        mimeType: mimeType || 'image/jpeg',
      });
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen.');
    } finally {
      setUploading(false);
    }
  }

  async function onPickImage() {
    if (!token || !validId || uploading) return;

    const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (!permission.granted) {
      setError('Bitte erlaube den Zugriff auf deine Fotos.');
      return;
    }

    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ['images'],
      quality: 0.85,
      allowsEditing: false,
    });
    if (result.canceled || !result.assets?.length) return;

    const asset = result.assets[0];
    const filename = asset.fileName || `bild-${Date.now()}.jpg`;
    await uploadImageFromUri(asset.uri, filename, asset.mimeType || 'image/jpeg');
  }

  async function onTakePhoto() {
    if (!token || !validId || uploading) return;

    const permission = await ImagePicker.requestCameraPermissionsAsync();
    if (!permission.granted) {
      setError('Bitte erlaube den Zugriff auf die Kamera.');
      return;
    }

    const result = await ImagePicker.launchCameraAsync({
      mediaTypes: ['images'],
      quality: 0.85,
      allowsEditing: false,
    });
    if (result.canceled || !result.assets?.length) return;

    const asset = result.assets[0];
    const filename = asset.fileName || `foto-${Date.now()}.jpg`;
    await uploadImageFromUri(asset.uri, filename, asset.mimeType || 'image/jpeg');
  }

  return (
    <ScrollView
      contentContainerStyle={styles.container}
      refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>
      {error ? <Text style={styles.error}>{error}</Text> : null}

      {loading ? (
        <View style={styles.loadingBox}>
          <ActivityIndicator />
          <Text style={styles.loadingText}>Objekt wird geladen...</Text>
        </View>
      ) : null}

      {!loading && plant ? (
        <>
          <View style={styles.card}>
            <View style={styles.sectionHeader}>
              <Text style={styles.title}>Informationen</Text>
              <Pressable
                style={styles.uploadButton}
                onPress={() =>
                  router.push({
                    pathname: '/more/wiki',
                    params: {
                      entityType: 'plants',
                      entityId: String(plantId),
                      title: `Objekt-Wiki: ${String(plant.name || plantId)}`,
                    },
                  })
                }>
                <Text style={styles.uploadButtonText}>Wiki</Text>
              </Pressable>
            </View>
            <View style={styles.table}>
              {rows.map((row) => (
                <View key={row.label} style={styles.row}>
                  <Text style={styles.label}>{row.label}</Text>
                  <Text style={styles.value}>{row.value}</Text>
                </View>
              ))}
            </View>
          </View>

          <View style={styles.card}>
            <View style={styles.sectionHeader}>
              <Text style={styles.sectionTitle}>Dokumente ({files.length})</Text>
            </View>
            <View style={styles.uploadActions}>
              <Pressable
                style={[styles.uploadButton, uploading ? styles.buttonDisabled : null]}
                onPress={onTakePhoto}
                disabled={uploading}>
                <Text style={styles.uploadButtonText}>{uploading ? 'Upload...' : 'Foto aufnehmen'}</Text>
              </Pressable>
              <Pressable
                style={[styles.uploadButton, uploading ? styles.buttonDisabled : null]}
                onPress={onPickImage}
                disabled={uploading}>
                <Text style={styles.uploadButtonText}>{uploading ? 'Upload...' : 'Bild auswählen'}</Text>
              </Pressable>
              <Pressable
                style={[styles.uploadButton, uploading ? styles.buttonDisabled : null]}
                onPress={onPickAndUpload}
                disabled={uploading}>
                <Text style={styles.uploadButtonText}>{uploading ? 'Upload...' : 'Dokument hochladen'}</Text>
              </Pressable>
            </View>

            {files.length === 0 ? (
              <Text style={styles.empty}>Noch keine Dokumente vorhanden.</Text>
            ) : (
              files.map((file) => (
                <Pressable key={file.id} style={styles.fileRow} onPress={() => onOpenFile(file)}>
                  <View style={styles.fileInfo}>
                    <Text style={styles.fileName} numberOfLines={2}>
                      {file.name || file.path?.split('/').pop() || file.id}
                    </Text>
                    <Text style={styles.fileMeta}>{file.mimeType || 'Datei'}</Text>
                  </View>
                </Pressable>
              ))
            )}
          </View>
        </>
      ) : null}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    gap: 12,
    backgroundColor: '#f9fafb',
  },
  card: {
    backgroundColor: '#ffffff',
    borderRadius: 12,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    padding: 12,
    gap: 8,
  },
  title: {
    color: '#111827',
    fontSize: 18,
    fontWeight: '700',
  },
  table: {
    borderWidth: 1,
    borderColor: '#e5e7eb',
    borderRadius: 10,
    overflow: 'hidden',
  },
  row: {
    borderBottomWidth: 1,
    borderBottomColor: '#e5e7eb',
    paddingHorizontal: 10,
    paddingVertical: 8,
    gap: 2,
  },
  label: {
    color: '#6b7280',
    fontSize: 12,
    textTransform: 'uppercase',
    fontWeight: '600',
  },
  value: {
    color: '#111827',
    fontSize: 14,
    fontWeight: '500',
  },
  sectionHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 10,
  },
  sectionTitle: {
    color: '#111827',
    fontSize: 16,
    fontWeight: '700',
  },
  uploadButton: {
    minHeight: 38,
    borderRadius: 9,
    backgroundColor: PRIMARY,
    paddingHorizontal: 12,
    alignItems: 'center',
    justifyContent: 'center',
  },
  uploadActions: {
    gap: 8,
  },
  uploadButtonText: {
    color: '#ffffff',
    fontWeight: '700',
    fontSize: 13,
  },
  fileRow: {
    borderWidth: 1,
    borderColor: '#e5e7eb',
    borderRadius: 10,
    padding: 10,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 10,
  },
  fileInfo: {
    flex: 1,
    minWidth: 0,
  },
  fileName: {
    color: '#111827',
    fontSize: 14,
    fontWeight: '600',
  },
  fileMeta: {
    color: '#6b7280',
    fontSize: 12,
    marginTop: 2,
  },
  empty: {
    color: '#6b7280',
    fontSize: 13,
    paddingVertical: 4,
  },
  loadingBox: {
    paddingVertical: 20,
    alignItems: 'center',
    gap: 8,
  },
  loadingText: {
    color: '#6b7280',
  },
  error: {
    color: '#dc2626',
    fontSize: 13,
  },
  buttonDisabled: {
    opacity: 0.6,
  },
});
