import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ActivityIndicator, Pressable, RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native';
import { router, useLocalSearchParams } from 'expo-router';

import {
  createStaffTimeEvent,
  fetchStaffTimeSpans,
  StaffTimeSpan,
  submitStaffTime,
} from '@/src/lib/api';
import { useAuth } from '@/src/providers/auth-provider';

const PRIMARY = '#69c350';

function formatDateTime(value: string | null): string {
  if (!value) return '-';
  const d = new Date(value);
  return d.toLocaleString('de-DE', {
    day: '2-digit',
    month: '2-digit',
    year: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function formatDuration(minutes: number): string {
  const h = Math.floor(minutes / 60);
  const m = minutes % 60;
  return `${h}h ${String(m).padStart(2, '0')}m`;
}

function getStateLabel(state: string): string {
  if (state === 'approved') return 'Genehmigt';
  if (state === 'submitted') return 'Eingereicht';
  if (state === 'rejected') return 'Abgelehnt';
  if (state === 'factual') return 'Faktisch';
  return 'Entwurf';
}

function getTypeLabel(type: string): string {
  if (type === 'vacation') return 'Urlaub';
  if (type === 'sick') return 'Krankheit';
  if (type === 'holiday') return 'Feiertag';
  if (type === 'other') return 'Sonstiges';
  return 'Arbeitszeit';
}

export default function TimeTrackingScreen() {
  const { token, user } = useAuth();
  const params = useLocalSearchParams<{ action?: string | string[] }>();

  const [entries, setEntries] = useState<StaffTimeSpan[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [actionLoading, setActionLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const currentUserId = useMemo(() => (user?.id ? String(user.id) : null), [user]);
  const handledActionRef = useRef<string | null>(null);

  const active = useMemo(() => entries.find((entry) => !entry.stopped_at) || null, [entries]);
  const incomingAction = useMemo(() => {
    const raw = Array.isArray(params.action) ? params.action[0] : params.action;
    return String(raw || '').toLowerCase();
  }, [params.action]);

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

      try {
        const spans = await fetchStaffTimeSpans(token, currentUserId);
        setEntries(spans);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Zeiten konnten nicht geladen werden.');
      } finally {
        setLoading(false);
        setRefreshing(false);
      }
    },
    [currentUserId, token]
  );

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

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

  const onStart = useCallback(async () => {
    if (!token || !currentUserId) return;
    setActionLoading(true);
    setError(null);

    try {
      await createStaffTimeEvent(token, {
        eventtype: 'work_start',
        eventtime: new Date().toISOString(),
        user_id: currentUserId,
        description: 'Arbeitszeit gestartet',
      });
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Starten fehlgeschlagen.');
    } finally {
      setActionLoading(false);
    }
  }, [currentUserId, token, load]);

  const onStop = useCallback(async () => {
    if (!token || !currentUserId || !active) return;
    setActionLoading(true);
    setError(null);

    try {
      await createStaffTimeEvent(token, {
        eventtype: 'work_end',
        eventtime: new Date().toISOString(),
        user_id: currentUserId,
      });
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Stoppen fehlgeschlagen.');
    } finally {
      setActionLoading(false);
    }
  }, [active, currentUserId, token, load]);

  async function onSubmit(entry: StaffTimeSpan) {
    if (!token || !entry.eventIds?.length) return;
    setActionLoading(true);
    setError(null);

    try {
      await submitStaffTime(token, entry.eventIds);
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Einreichen fehlgeschlagen.');
    } finally {
      setActionLoading(false);
    }
  }

  const onSubmitAll = useCallback(async () => {
    if (!token) return;

    const submitCandidates = entries.filter(
      (entry) => (entry.state === 'draft' || entry.state === 'factual') && !!entry.stopped_at && !!entry.eventIds?.length
    );

    if (submitCandidates.length === 0) return;

    setActionLoading(true);
    setError(null);

    try {
      for (const entry of submitCandidates) {
        await submitStaffTime(token, entry.eventIds);
      }
      await load(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Einreichen fehlgeschlagen.');
    } finally {
      setActionLoading(false);
    }
  }, [entries, load, token]);

  useEffect(() => {
    if (!token || !currentUserId) return;
    if (!incomingAction) return;
    if (handledActionRef.current === incomingAction) return;

    if (incomingAction === 'start' && !active) {
      handledActionRef.current = incomingAction;
      void onStart().finally(() => router.replace('/(tabs)/time'));
      return;
    }

    if (incomingAction === 'stop' && active) {
      handledActionRef.current = incomingAction;
      void onStop().finally(() => router.replace('/(tabs)/time'));
      return;
    }

    if (incomingAction === 'submit') {
      handledActionRef.current = incomingAction;
      void onSubmitAll().finally(() => router.replace('/(tabs)/time'));
      return;
    }

    handledActionRef.current = incomingAction;
    void router.replace('/(tabs)/time');
  }, [active, currentUserId, incomingAction, onStart, onStop, onSubmitAll, token]);

  return (
    <ScrollView
      contentContainerStyle={styles.container}
      refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>
      <View style={styles.statusCard}>
        <Text style={styles.statusLabel}>Aktive Zeit</Text>
        <Text style={styles.statusValue}>
          {active ? `Läuft seit ${formatDateTime(active.started_at)}` : 'Keine aktive Zeit'}
        </Text>

        <View style={styles.statusActions}>
          {active ? (
            <Pressable
              style={[styles.stopButton, actionLoading ? styles.buttonDisabled : null]}
              onPress={onStop}
              disabled={actionLoading}>
              <Text style={styles.stopButtonText}>Stop</Text>
            </Pressable>
          ) : (
            <Pressable
              style={[styles.startButton, actionLoading ? styles.buttonDisabled : null]}
              onPress={onStart}
              disabled={actionLoading}>
              <Text style={styles.startButtonText}>Start</Text>
            </Pressable>
          )}
        </View>
      </View>

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

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

      {!loading && entries.length === 0 ? <Text style={styles.empty}>Keine Zeiteinträge vorhanden.</Text> : null}

      {!loading &&
        entries.map((entry) => {
          const canSubmit = (entry.state === 'draft' || entry.state === 'factual') && !!entry.stopped_at;

          return (
            <View key={`${entry.id}-${entry.started_at}`} style={styles.entryCard}>
              <View style={styles.entryHeader}>
                <Text style={styles.entryType}>{getTypeLabel(entry.type)}</Text>
                <Text style={styles.entryState}>{getStateLabel(entry.state)}</Text>
              </View>

              <Text style={styles.entryTime}>Start: {formatDateTime(entry.started_at)}</Text>
              <Text style={styles.entryTime}>
                Ende: {entry.stopped_at ? formatDateTime(entry.stopped_at) : 'läuft...'}
              </Text>
              <Text style={styles.entryTime}>Dauer: {formatDuration(entry.duration_minutes)}</Text>

              {entry.description ? <Text style={styles.entryDescription}>{entry.description}</Text> : null}

              {canSubmit ? (
                <View style={styles.entryActions}>
                  <Pressable
                    style={[styles.actionButton, actionLoading ? styles.buttonDisabled : null]}
                    onPress={() => onSubmit(entry)}
                    disabled={actionLoading}>
                    <Text style={styles.actionButtonText}>Einreichen</Text>
                  </Pressable>
                </View>
              ) : null}
            </View>
          );
        })}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    gap: 12,
    backgroundColor: '#f9fafb',
  },
  statusCard: {
    backgroundColor: '#ffffff',
    borderRadius: 12,
    padding: 12,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    gap: 8,
  },
  statusLabel: {
    color: '#6b7280',
    fontSize: 12,
    textTransform: 'uppercase',
  },
  statusValue: {
    color: '#111827',
    fontSize: 16,
    fontWeight: '600',
  },
  statusActions: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  startButton: {
    minHeight: 40,
    borderRadius: 10,
    backgroundColor: PRIMARY,
    paddingHorizontal: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  startButtonText: {
    color: '#ffffff',
    fontWeight: '700',
  },
  stopButton: {
    minHeight: 40,
    borderRadius: 10,
    backgroundColor: '#dc2626',
    paddingHorizontal: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  stopButtonText: {
    color: '#ffffff',
    fontWeight: '700',
  },
  error: {
    color: '#dc2626',
    fontSize: 13,
  },
  loadingBox: {
    padding: 16,
    alignItems: 'center',
    gap: 8,
  },
  loadingText: {
    color: '#6b7280',
  },
  empty: {
    color: '#6b7280',
    textAlign: 'center',
    paddingVertical: 16,
  },
  entryCard: {
    backgroundColor: '#ffffff',
    borderRadius: 12,
    padding: 12,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    gap: 6,
  },
  entryHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 8,
  },
  entryType: {
    color: '#111827',
    fontWeight: '600',
  },
  entryState: {
    color: '#3d7a30',
    fontWeight: '600',
    backgroundColor: '#eff9ea',
    borderRadius: 999,
    paddingHorizontal: 8,
    paddingVertical: 3,
    fontSize: 12,
    overflow: 'hidden',
  },
  entryTime: {
    color: '#4b5563',
    fontSize: 13,
  },
  entryDescription: {
    color: '#374151',
    fontSize: 14,
  },
  entryActions: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
    marginTop: 4,
  },
  actionButton: {
    minHeight: 36,
    borderRadius: 8,
    backgroundColor: '#0ea5e9',
    paddingHorizontal: 10,
    alignItems: 'center',
    justifyContent: 'center',
  },
  actionButtonText: {
    color: '#ffffff',
    fontWeight: '600',
    fontSize: 12,
  },
  buttonDisabled: {
    opacity: 0.6,
  },
});
