import { useCallback, useEffect, useState } from 'react';
import { Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';
import { router } from 'expo-router';

import { DEFAULT_API_BASE_URL } from '@/src/config/env';
import { sendMobileTestPush } from '@/src/lib/api';
import { registerDeviceForPush } from '@/src/lib/push-registration';
import {
  getApiBaseUrlSync,
  hydrateApiBaseUrl,
  resetApiBaseUrl,
  serverStorageInfo,
  setApiBaseUrl,
} from '@/src/lib/server-config';
import { useAuth } from '@/src/providers/auth-provider';

const PRIMARY = '#69c350';

function isValidServerUrl(value: string): boolean {
  return /^https?:\/\/.+/i.test(value.trim());
}

export default function SettingsScreen() {
  const { logout, token } = useAuth();
  const [serverUrl, setServerUrlInput] = useState(getApiBaseUrlSync());
  const [savedUrl, setSavedUrl] = useState(getApiBaseUrlSync());
  const [submitting, setSubmitting] = useState(false);
  const [pushSubmitting, setPushSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  const loadConfig = useCallback(async () => {
    const current = await hydrateApiBaseUrl();
    setServerUrlInput(current);
    setSavedUrl(current);
  }, []);

  useEffect(() => {
    void loadConfig();
  }, [loadConfig]);

  async function onSave() {
    setError(null);
    setSuccess(null);

    if (!isValidServerUrl(serverUrl)) {
      setError('Bitte eine gültige URL mit http:// oder https:// eingeben.');
      return;
    }

    setSubmitting(true);
    try {
      const normalized = await setApiBaseUrl(serverUrl);
      setServerUrlInput(normalized);
      setSavedUrl(normalized);
      setSuccess('Server-Instanz gespeichert.');

      if (token) {
        await logout();
        router.replace('/login');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Server-Instanz konnte nicht gespeichert werden.');
    } finally {
      setSubmitting(false);
    }
  }

  async function onResetToDefault() {
    setError(null);
    setSuccess(null);
    setSubmitting(true);

    try {
      const fallback = await resetApiBaseUrl();
      setServerUrlInput(fallback);
      setSavedUrl(fallback);
      setSuccess('Auf Standard-Server zurückgesetzt.');

      if (token) {
        await logout();
        router.replace('/login');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Zuruecksetzen fehlgeschlagen.');
    } finally {
      setSubmitting(false);
    }
  }

  async function onRegisterPush() {
    setError(null);
    setSuccess(null);

    if (!token) {
      setError('Bitte zuerst anmelden, um dieses Gerät für Push zu registrieren.');
      return;
    }

    setPushSubmitting(true);
    try {
      const result = await registerDeviceForPush(token);
      setSuccess(`Push registriert: ${result.centralDeviceId || result.id || 'aktiv'}`);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Push-Registrierung fehlgeschlagen.');
    } finally {
      setPushSubmitting(false);
    }
  }

  async function onSendTestPush() {
    setError(null);
    setSuccess(null);

    if (!token) {
      setError('Bitte zuerst anmelden, um eine Testnachricht zu senden.');
      return;
    }

    setPushSubmitting(true);
    try {
      const result = await sendMobileTestPush(token);
      setSuccess(`Testnachricht angefordert: ${result.accepted} akzeptiert, ${result.rejected} abgelehnt.`);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Testnachricht konnte nicht gesendet werden.');
    } finally {
      setPushSubmitting(false);
    }
  }

  const isDirty = serverUrl.trim() !== savedUrl;

  return (
    <ScrollView contentContainerStyle={styles.container}>
      <View style={styles.card}>
        <Text style={styles.title}>Server-Instanz</Text>
        <Text style={styles.hint}>
          Hinterlege hier die URL deiner eigenen FEDEO-Server-Instanz. Nach dem Speichern wird die Session
          neu gestartet.
        </Text>

        <Text style={styles.label}>Server URL</Text>
        <TextInput
          value={serverUrl}
          onChangeText={setServerUrlInput}
          autoCapitalize="none"
          autoCorrect={false}
          keyboardType="url"
          placeholder="https://dein-server.tld"
          placeholderTextColor="#9ca3af"
          style={styles.input}
        />

        <Text style={styles.meta}>Aktiv: {savedUrl}</Text>
        <Text style={styles.meta}>Standard: {DEFAULT_API_BASE_URL}</Text>
        <Text style={styles.meta}>Storage: {serverStorageInfo.mode}</Text>

        {error ? <Text style={styles.error}>{error}</Text> : null}
        {success ? <Text style={styles.success}>{success}</Text> : null}

        <View style={styles.actions}>
          <Pressable
            style={[styles.saveButton, (!isDirty || submitting) ? styles.buttonDisabled : null]}
            onPress={onSave}
            disabled={!isDirty || submitting}>
            <Text style={styles.saveButtonText}>{submitting ? 'Speichern...' : 'Speichern'}</Text>
          </Pressable>

          <Pressable
            style={[styles.resetButton, submitting ? styles.buttonDisabled : null]}
            onPress={onResetToDefault}
            disabled={submitting}>
            <Text style={styles.resetButtonText}>Auf Standard zurücksetzen</Text>
          </Pressable>
        </View>
      </View>

      <View style={styles.card}>
        <Text style={styles.title}>Mobile Push</Text>
        <Text style={styles.hint}>
          Registriert dieses Gerät bei deiner FEDEO-Instanz und leitet den nativen Push-Token an den zentralen
          Push-Server weiter.
        </Text>

        <View style={styles.actions}>
          <Pressable
            style={[styles.saveButton, (!token || pushSubmitting) ? styles.buttonDisabled : null]}
            onPress={onRegisterPush}
            disabled={!token || pushSubmitting}>
            <Text style={styles.saveButtonText}>{pushSubmitting ? 'Bitte warten...' : 'Gerät registrieren'}</Text>
          </Pressable>

          <Pressable
            style={[styles.resetButton, (!token || pushSubmitting) ? styles.buttonDisabled : null]}
            onPress={onSendTestPush}
            disabled={!token || pushSubmitting}>
            <Text style={styles.resetButtonText}>Testnachricht senden</Text>
          </Pressable>
        </View>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    backgroundColor: '#f9fafb',
    padding: 16,
    gap: 12,
  },
  card: {
    backgroundColor: '#ffffff',
    borderWidth: 1,
    borderColor: '#e5e7eb',
    borderRadius: 12,
    padding: 14,
    gap: 10,
  },
  title: {
    color: '#111827',
    fontSize: 18,
    fontWeight: '700',
  },
  hint: {
    color: '#6b7280',
    fontSize: 13,
    lineHeight: 18,
  },
  label: {
    color: '#374151',
    fontSize: 13,
    fontWeight: '600',
    marginTop: 2,
  },
  input: {
    borderWidth: 1,
    borderColor: '#d1d5db',
    borderRadius: 10,
    paddingHorizontal: 12,
    paddingVertical: 10,
    fontSize: 15,
    color: '#111827',
    backgroundColor: '#ffffff',
  },
  meta: {
    color: '#6b7280',
    fontSize: 12,
  },
  actions: {
    gap: 8,
    marginTop: 6,
  },
  saveButton: {
    minHeight: 42,
    backgroundColor: PRIMARY,
    borderRadius: 10,
    alignItems: 'center',
    justifyContent: 'center',
  },
  saveButtonText: {
    color: '#ffffff',
    fontSize: 15,
    fontWeight: '700',
  },
  resetButton: {
    minHeight: 42,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#d1d5db',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#ffffff',
  },
  resetButtonText: {
    color: '#374151',
    fontSize: 14,
    fontWeight: '600',
  },
  buttonDisabled: {
    opacity: 0.6,
  },
  error: {
    color: '#dc2626',
    fontSize: 13,
  },
  success: {
    color: '#166534',
    fontSize: 13,
  },
});
