import { useState, useCallback } from 'react';
import {
  Box, Paper, Typography, TextField, Button, Alert,
  CircularProgress, Divider, Autocomplete, Chip,
} from '@mui/material';
import DeleteSweepIcon from '@mui/icons-material/DeleteSweep';
import RestartAltIcon from '@mui/icons-material/RestartAlt';
import GroupAddIcon from '@mui/icons-material/GroupAdd';
import { api } from '../../services/api';
import { adminApi } from '../../services/admin';
import { useNotification } from '../../contexts/NotificationContext';
import { ConfirmDialog } from '../templates';
import { useQuery } from '@tanstack/react-query';
import type { UserOverview } from '../../types/admin.types';

interface CleanupSection {
  key: string;
  label: string;
  description: string;
  defaultDays: number;
}

const SECTIONS: CleanupSection[] = [
  { key: 'notifications', label: 'Benachrichtigungen', description: 'Alte Benachrichtigungen aller Benutzer entfernen.', defaultDays: 90 },
  { key: 'audit-log', label: 'Audit-Log', description: 'Alte Audit-Log Eintraege entfernen.', defaultDays: 365 },
  { key: 'events', label: 'Veranstaltungen', description: 'Vergangene Veranstaltungen entfernen (nach Enddatum).', defaultDays: 365 },
  { key: 'bookings', label: 'Fahrzeugbuchungen', description: 'Abgeschlossene oder stornierte Buchungen entfernen.', defaultDays: 180 },
  { key: 'orders', label: 'Bestellungen', description: 'Abgeschlossene Bestellungen entfernen.', defaultDays: 365 },
  { key: 'vehicle-history', label: 'Fahrzeug-Wartungslog', description: 'Alte Fahrzeug-Wartungseintraege entfernen.', defaultDays: 730 },
  { key: 'equipment-history', label: 'Ausruestungs-Wartungslog', description: 'Alte Ausruestungs-Wartungseintraege entfernen.', defaultDays: 730 },
  { key: 'checklist-history', label: 'Checklisten-Historie', description: 'Alte Checklisten-Ausfuehrungen entfernen.', defaultDays: 365 },
];

interface ResetSection {
  key: string;
  label: string;
  description: string;
}

const RESET_SECTIONS: ResetSection[] = [
  { key: 'reset-bestellungen', label: 'Bestellungen zuruecksetzen', description: 'Alle Bestellungen, Positionen, Dateien, Erinnerungen und Historie loeschen und Nummern zuruecksetzen.' },
  { key: 'reset-ausruestung-anfragen', label: 'Interne Bestellungen zuruecksetzen', description: 'Alle internen Bestellungen und zugehoerige Positionen loeschen und Nummern zuruecksetzen.' },
  { key: 'reset-issues', label: 'Issues zuruecksetzen', description: 'Alle Issues und Kommentare loeschen und Nummern zuruecksetzen.' },
  { key: 'reset-checklist-history', label: 'Checklisten-Historie zuruecksetzen', description: 'Alle Checklisten-Ausfuehrungen und Faelligkeiten loeschen und Nummern zuruecksetzen.' },
  { key: 'reset-buchhaltung-transaktionen', label: 'Buchhaltung: Transaktionen loeschen', description: 'Alle Buchungen und Transaktionen loeschen und Nummerierung zuruecksetzen. Konten und Haushaltsjahre bleiben erhalten.' },
  { key: 'reset-buchhaltung-konten', label: 'Buchhaltung: Konten loeschen', description: 'Alle Konten und alle zugehoerigen Transaktionen loeschen und Nummerierung zuruecksetzen. Haushaltsjahre bleiben erhalten.' },
  { key: 'reset-buchhaltung-bankkonten', label: 'Buchhaltung: Bankkonten loeschen', description: 'Alle Bankkonten loeschen und Nummerierung zuruecksetzen.' },
  { key: 'reset-persoenliche-ausruestung', label: 'Persoenliche Ausruestung zuruecksetzen', description: 'Alle persoenlichen Ausruestungszuweisungen loeschen. Zuordnungen in Anfragen werden zurueckgesetzt.' },
];

interface SectionState {
  days: number;
  previewCount: number | null;
  loading: boolean;
}

export default function DataManagementTab() {
  const { showSuccess, showError } = useNotification();

  // ── FDISK purge ──
  const { data: users = [], isLoading: usersLoading } = useQuery<UserOverview[]>({
    queryKey: ['admin', 'users'],
    queryFn: adminApi.getUsers,
  });
  const [selectedUsers, setSelectedUsers] = useState<UserOverview[]>([]);
  const [fdiskInput, setFdiskInput] = useState('');
  const [purging, setPurging] = useState(false);
  const [purgeConfirmOpen, setPurgeConfirmOpen] = useState(false);

  const handleAddUser = useCallback((user: UserOverview) => {
    setSelectedUsers(prev => prev.some(u => u.id === user.id) ? prev : [...prev, user]);
  }, []);

  const handleRemoveUser = useCallback((userId: string) => {
    setSelectedUsers(prev => prev.filter(u => u.id !== userId));
  }, []);

  const handleAddAll = useCallback(() => {
    setSelectedUsers(users);
  }, [users]);

  const handlePurge = useCallback(async () => {
    if (selectedUsers.length === 0) return;
    setPurging(true);
    let totalDeleted = 0;
    let errorCount = 0;
    for (const user of selectedUsers) {
      try {
        const result = await adminApi.purgeFdiskData(user.id);
        totalDeleted += result.profileFieldsCleared + result.ausbildungen + result.befoerderungen + result.untersuchungen + result.fahrgenehmigungen;
      } catch {
        errorCount++;
      }
    }
    setPurging(false);
    setPurgeConfirmOpen(false);
    if (errorCount === 0) {
      showSuccess(`${totalDeleted} FDISK-Eintraege fuer ${selectedUsers.length} ${selectedUsers.length === 1 ? 'Benutzer' : 'Benutzer'} geloescht`);
      setSelectedUsers([]);
    } else {
      showError(`${errorCount} von ${selectedUsers.length} Benutzern konnten nicht verarbeitet werden`);
    }
  }, [selectedUsers, showSuccess, showError]);

  const [states, setStates] = useState<Record<string, SectionState>>(() =>
    Object.fromEntries(SECTIONS.map(s => [s.key, { days: s.defaultDays, previewCount: null, loading: false }]))
  );

  const [confirmDialog, setConfirmDialog] = useState<{ key: string; label: string; count: number } | null>(null);
  const [deleting, setDeleting] = useState(false);

  // Reset sections state
  const [resetStates, setResetStates] = useState<Record<string, { previewCount: number | null; loading: boolean }>>(() =>
    Object.fromEntries(RESET_SECTIONS.map(s => [s.key, { previewCount: null, loading: false }]))
  );
  const [resetConfirmDialog, setResetConfirmDialog] = useState<{ key: string; label: string; count: number } | null>(null);
  const [resetDeleting, setResetDeleting] = useState(false);

  const updateState = useCallback((key: string, partial: Partial<SectionState>) => {
    setStates(prev => ({ ...prev, [key]: { ...prev[key], ...partial } }));
  }, []);

  const handlePreview = useCallback(async (key: string) => {
    const s = states[key];
    if (!s || s.days < 1) return;
    updateState(key, { loading: true, previewCount: null });
    try {
      const res = await api.delete(`/api/admin/cleanup/${key}`, { data: { olderThanDays: s.days, confirm: false } });
      updateState(key, { previewCount: res.data.data.count, loading: false });
    } catch {
      showError('Vorschau konnte nicht geladen werden');
      updateState(key, { loading: false });
    }
  }, [states, updateState, showError]);

  const handleDelete = useCallback(async () => {
    if (!confirmDialog) return;
    const { key } = confirmDialog;
    const s = states[key];
    setDeleting(true);
    try {
      const res = await api.delete(`/api/admin/cleanup/${key}`, { data: { olderThanDays: s.days, confirm: true } });
      const deleted = res.data.data.count;
      showSuccess(`${deleted} Eintraege geloescht`);
      updateState(key, { previewCount: null });
    } catch {
      showError('Loeschen fehlgeschlagen');
    } finally {
      setDeleting(false);
      setConfirmDialog(null);
    }
  }, [confirmDialog, states, updateState, showSuccess, showError]);

  const handleResetPreview = useCallback(async (key: string) => {
    setResetStates(prev => ({ ...prev, [key]: { previewCount: null, loading: true } }));
    try {
      const res = await api.delete(`/api/admin/cleanup/${key}`);
      setResetStates(prev => ({ ...prev, [key]: { previewCount: res.data.data.count, loading: false } }));
    } catch {
      showError('Vorschau konnte nicht geladen werden');
      setResetStates(prev => ({ ...prev, [key]: { ...prev[key], loading: false } }));
    }
  }, [showError]);

  const handleResetDelete = useCallback(async () => {
    if (!resetConfirmDialog) return;
    const { key } = resetConfirmDialog;
    setResetDeleting(true);
    try {
      const res = await api.delete(`/api/admin/cleanup/${key}?confirm=true`);
      const deleted = res.data.data.count;
      showSuccess(`${deleted} Eintraege geloescht und Nummern zurueckgesetzt`);
      setResetStates(prev => ({ ...prev, [key]: { previewCount: null, loading: false } }));
    } catch {
      showError('Zuruecksetzen fehlgeschlagen');
    } finally {
      setResetDeleting(false);
      setResetConfirmDialog(null);
    }
  }, [resetConfirmDialog, showSuccess, showError]);

  return (
    <Box sx={{ maxWidth: 800 }}>
      <Typography variant="h6" sx={{ mb: 1 }}>Datenverwaltung</Typography>
      <Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
        Alte Daten bereinigen, um die Datenbank schlank zu halten. Geloeschte Daten koennen nicht wiederhergestellt werden.
      </Typography>

      {/* FDISK data purge */}
      <Paper sx={{ p: 3, mb: 3 }}>
        <Typography variant="subtitle1" fontWeight={600} sx={{ mb: 1 }}>
          FDISK-Daten loeschen
        </Typography>
        <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
          Loescht alle FDISK-synchronisierten Daten der ausgewaehlten Benutzer: Profilfelder, Ausbildungen,
          Befoerderungen, Untersuchungen und Fahrgenehmigungen. Beim naechsten FDISK-Sync werden
          die Daten erneut importiert.
        </Typography>

        <Box sx={{ display: 'flex', gap: 2, alignItems: 'center', flexWrap: 'wrap' }}>
          <Autocomplete
            options={users.filter(u => !selectedUsers.some(s => s.id === u.id))}
            loading={usersLoading}
            value={null}
            inputValue={fdiskInput}
            onInputChange={(_e, val, reason) => {
              if (reason === 'input') setFdiskInput(val);
            }}
            onChange={(_e, user) => {
              if (user) {
                handleAddUser(user);
                setFdiskInput('');
              }
            }}
            getOptionLabel={(u) => `${u.name || 'Kein Name'} (${u.email})`}
            isOptionEqualToValue={(a, b) => a.id === b.id}
            sx={{ minWidth: 320, flex: 1 }}
            renderInput={(params) => (
              <TextField {...params} label="Benutzer hinzufuegen" size="small" />
            )}
          />

          <Button
            variant="outlined"
            size="small"
            startIcon={<GroupAddIcon />}
            onClick={handleAddAll}
            disabled={usersLoading || users.length === 0 || selectedUsers.length === users.length}
          >
            Alle hinzufuegen
          </Button>
        </Box>

        {selectedUsers.length > 0 && (
          <>
            <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mt: 2 }}>
              {selectedUsers.map(u => (
                <Chip
                  key={u.id}
                  label={u.name || u.email}
                  onDelete={() => handleRemoveUser(u.id)}
                  size="small"
                />
              ))}
            </Box>
            <Box sx={{ mt: 2 }}>
              <Button
                variant="contained"
                color="error"
                disabled={purging}
                startIcon={purging ? <CircularProgress size={16} /> : <DeleteSweepIcon />}
                onClick={() => setPurgeConfirmOpen(true)}
              >
                FDISK-Daten loeschen ({selectedUsers.length})
              </Button>
            </Box>
          </>
        )}
      </Paper>

      <ConfirmDialog
        open={purgeConfirmOpen}
        onClose={() => !purging && setPurgeConfirmOpen(false)}
        onConfirm={handlePurge}
        title="FDISK-Daten loeschen?"
        message={selectedUsers.length > 0 ? (
          <>
            Alle FDISK-synchronisierten Daten fuer{' '}
            {selectedUsers.length === 1
              ? <strong>{selectedUsers[0].name ?? selectedUsers[0].email}</strong>
              : <strong>{selectedUsers.length} Benutzer</strong>
            }{' '}
            werden geloescht:
            <ul style={{ margin: '8px 0', paddingLeft: 20 }}>
              <li>Profilfelder (Status, Dienstgrad, Geburtsdatum, Geburtsort, Geschlecht, Beruf, Wohnort, PLZ)</li>
              <li>Alle Ausbildungen, Befoerderungen, Untersuchungen und Fahrgenehmigungen</li>
            </ul>
            Die Standesbuchnummer bleibt erhalten. Beim naechsten FDISK-Sync werden die Daten erneut importiert.
          </>
        ) : ''}
        confirmLabel="Endgueltig loeschen"
        confirmColor="error"
        isLoading={purging}
      />

      {SECTIONS.map((section, idx) => {
        const s = states[section.key];
        return (
          <Paper key={section.key} sx={{ p: 3, mb: 2 }}>
            <Typography variant="subtitle1" fontWeight={600}>{section.label}</Typography>
            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>{section.description}</Typography>

            <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flexWrap: 'wrap' }}>
              <TextField
                label="Aelter als (Tage)"
                type="number"
                size="small"
                value={s.days}
                onChange={e => {
                  const v = parseInt(e.target.value, 10);
                  if (v > 0) updateState(section.key, { days: v, previewCount: null });
                }}
                sx={{ width: 160 }}
                inputProps={{ min: 1, max: 3650 }}
              />

              <Button
                variant="outlined"
                size="small"
                onClick={() => handlePreview(section.key)}
                disabled={s.loading}
                startIcon={s.loading ? <CircularProgress size={16} /> : undefined}
              >
                Vorschau
              </Button>

              {s.previewCount !== null && (
                <>
                  <Alert severity={s.previewCount > 0 ? 'warning' : 'info'} sx={{ py: 0 }}>
                    {s.previewCount} {s.previewCount === 1 ? 'Eintrag' : 'Eintraege'} gefunden
                  </Alert>

                  {s.previewCount > 0 && (
                    <Button
                      variant="contained"
                      color="error"
                      size="small"
                      startIcon={<DeleteSweepIcon />}
                      onClick={() => setConfirmDialog({ key: section.key, label: section.label, count: s.previewCount! })}
                    >
                      Loeschen
                    </Button>
                  )}
                </>
              )}
            </Box>

            {idx < SECTIONS.length - 1 && <Divider sx={{ mt: 2, display: 'none' }} />}
          </Paper>
        );
      })}

      <ConfirmDialog
        open={!!confirmDialog}
        onClose={() => setConfirmDialog(null)}
        onConfirm={handleDelete}
        title="Daten loeschen?"
        message={confirmDialog ? (
          <>
            <strong>{confirmDialog.count}</strong> {confirmDialog.count === 1 ? 'Eintrag' : 'Eintraege'} aus <strong>{confirmDialog.label}</strong> werden
            unwiderruflich geloescht. Dieser Vorgang kann nicht rueckgaengig gemacht werden.
          </>
        ) : ''}
        confirmLabel="Endgueltig loeschen"
        confirmColor="error"
        isLoading={deleting}
      />

      {/* ---- Reset / Truncate sections ---- */}
      <Divider sx={{ my: 4 }} />
      <Typography variant="h6" sx={{ mb: 1 }}>Daten zuruecksetzen</Typography>
      <Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
        Alle Eintraege loeschen und Nummern (IDs) auf 1 zuruecksetzen. Abhaengige Daten werden ebenfalls geloescht.
      </Typography>

      {RESET_SECTIONS.map((section) => {
        const rs = resetStates[section.key];
        return (
          <Paper key={section.key} sx={{ p: 3, mb: 2 }}>
            <Typography variant="subtitle1" fontWeight={600}>{section.label}</Typography>
            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>{section.description}</Typography>

            <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, flexWrap: 'wrap' }}>
              <Button
                variant="outlined"
                size="small"
                onClick={() => handleResetPreview(section.key)}
                disabled={rs?.loading}
                startIcon={rs?.loading ? <CircularProgress size={16} /> : undefined}
              >
                Vorschau
              </Button>

              {rs?.previewCount !== null && rs?.previewCount !== undefined && (
                <>
                  <Alert severity={rs.previewCount > 0 ? 'warning' : 'info'} sx={{ py: 0 }}>
                    {rs.previewCount} {rs.previewCount === 1 ? 'Eintrag' : 'Eintraege'} vorhanden
                  </Alert>

                  {rs.previewCount > 0 && (
                    <Button
                      variant="contained"
                      color="error"
                      size="small"
                      startIcon={<RestartAltIcon />}
                      onClick={() => setResetConfirmDialog({ key: section.key, label: section.label, count: rs.previewCount! })}
                    >
                      Zuruecksetzen
                    </Button>
                  )}
                </>
              )}
            </Box>
          </Paper>
        );
      })}

      <ConfirmDialog
        open={!!resetConfirmDialog}
        onClose={() => setResetConfirmDialog(null)}
        onConfirm={handleResetDelete}
        title="Daten zuruecksetzen?"
        message={resetConfirmDialog ? (
          <>
            <strong>{resetConfirmDialog.count}</strong> {resetConfirmDialog.count === 1 ? 'Eintrag' : 'Eintraege'} aus <strong>{resetConfirmDialog.label}</strong> werden
            unwiderruflich geloescht und die Nummerierung auf 1 zurueckgesetzt. Dieser Vorgang kann nicht rueckgaengig gemacht werden.
          </>
        ) : ''}
        confirmLabel="Endgueltig zuruecksetzen"
        confirmColor="error"
        isLoading={resetDeleting}
      />
    </Box>
  );
}
