import { useState, useRef, useEffect, useCallback } from 'react';
import {
  Container,
  Typography,
  Card,
  CardContent,
  Grid,
  FormGroup,
  FormControlLabel,
  Switch,
  Divider,
  Box,
  ToggleButtonGroup,
  ToggleButton,
  CircularProgress,
  Button,
  Chip,
  IconButton,
  List,
  ListItem,
  ListItemText,
} from '@mui/material';
import { Settings as SettingsIcon, Notifications, Palette, Language, SettingsBrightness, LightMode, DarkMode, Widgets, Cloud, LinkOff, Forum, Person, OpenInNew, Sort, Restore, DragIndicator } from '@mui/icons-material';
import {
  Schedule as ScheduleIcon,
} from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import {
  DndContext,
  PointerSensor,
  useSensor,
  useSensors,
  closestCenter,
} from '@dnd-kit/core';
import type { DragEndEvent } from '@dnd-kit/core';
import {
  SortableContext,
  verticalListSortingStrategy,
  arrayMove,
  useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import { useThemeMode } from '../contexts/ThemeContext';
import { preferencesApi } from '../services/settings';
import { WIDGETS, WidgetKey } from '../constants/widgets';
import { nextcloudApi } from '../services/nextcloud';
import { scheduledMessagesApi } from '../services/scheduledMessages';
import { useNotification } from '../contexts/NotificationContext';
import { useAuth } from '../contexts/AuthContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import type { MessageType } from '../types/scheduledMessages.types';

const MESSAGE_TYPE_LABELS: Record<MessageType, string> = {
  event_summary: 'Terminübersicht',
  birthday_list: 'Geburtstagsliste',
  dienstjubilaeen: 'Dienstjubiläen',
  fahrzeug_status: 'Fahrzeugstatus',
  fahrzeug_event: 'Fahrzeug außer Dienst',
  bestellungen: 'Offene Bestellungen',
};

const POLL_INTERVAL = 2000;
const POLL_TIMEOUT = 5 * 60 * 1000;

// Ordered list of nav items eligible for reordering (mirrors baseNavigationItems, excluding admin/settings)
const ORDERABLE_NAV_ITEMS = [
  { text: 'Dashboard', path: '/dashboard', permission: undefined as string | undefined },
  { text: 'Chat', path: '/chat', permission: undefined as string | undefined },
  { text: 'Kalender', path: '/kalender', permission: 'kalender:view' },
  { text: 'Fahrzeugbuchungen', path: '/fahrzeugbuchungen', permission: 'fahrzeugbuchungen:view' },
  { text: 'Fahrzeuge', path: '/fahrzeuge', permission: 'fahrzeuge:view' },
  { text: 'Ausrüstung', path: '/ausruestung', permission: 'ausruestung:view' },
  { text: 'Pers. Ausrüstung', path: '/persoenliche-ausruestung', permission: 'persoenliche_ausruestung:view' },
  { text: 'Mitglieder', path: '/mitglieder', permission: 'mitglieder:view_own' },
  { text: 'Atemschutz', path: '/atemschutz', permission: 'atemschutz:view' },
  { text: 'Wissen', path: '/wissen', permission: 'wissen:view' },
  { text: 'Bestellungen', path: '/bestellungen', permission: 'bestellungen:view' },
  { text: 'Interne Bestellungen', path: '/ausruestungsanfrage', permission: 'ausruestungsanfrage:view' },
  { text: 'Checklisten', path: '/checklisten', permission: 'checklisten:view' },
  { text: 'Buchhaltung', path: '/buchhaltung', permission: 'buchhaltung:view' },
  { text: 'Issues', path: '/issues', permission: 'issues:view_own' },
  { text: 'Geplante Nachrichten', path: '/geplante-nachrichten', permission: 'scheduled_messages:view' },
];

function SortableNavItem({ id, text }: { id: string; text: string }) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
  return (
    <ListItem
      ref={setNodeRef}
      disablePadding
      sx={{
        py: 0.25,
        opacity: isDragging ? 0.4 : 1,
        transform: CSS.Transform.toString(transform),
        transition,
      }}
    >
      <IconButton
        size="small"
        {...attributes}
        {...listeners}
        sx={{ cursor: 'grab', touchAction: 'none', mr: 0.5 }}
        disableRipple
      >
        <DragIndicator fontSize="small" />
      </IconButton>
      <ListItemText primary={text} primaryTypographyProps={{ variant: 'body2' }} />
    </ListItem>
  );
}

function SubscriptionsCard() {
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const { data, isLoading } = useQuery({
    queryKey: ['scheduled-messages'],
    queryFn: scheduledMessagesApi.getAll,
  });

  const rules = (data?.data ?? []).filter(
    (rule) =>
      rule.subscribable &&
      (rule.allowed_groups.length === 0 ||
        rule.allowed_groups.some((g) => user?.groups?.includes(g))),
  );

  const handleToggle = async (ruleId: string, isSubscribed: boolean) => {
    if (isSubscribed) {
      await scheduledMessagesApi.unsubscribe(ruleId);
    } else {
      try {
        const roomResult = await scheduledMessagesApi.getMyBotRoom();
        await scheduledMessagesApi.subscribe(ruleId, roomResult.data.room_token);
      } catch {
        return; // silently skip — user will see no change in toggle
      }
    }
    queryClient.invalidateQueries({ queryKey: ['scheduled-messages'] });
  };

  return (
    <Grid item xs={12} md={6}>
      <Card>
        <CardContent>
          <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
            <ScheduleIcon color="primary" sx={{ mr: 2 }} />
            <Typography variant="h6">Nachrichten-Abonnements</Typography>
          </Box>
          <Divider sx={{ mb: 2 }} />
          {isLoading ? (
            <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
              <CircularProgress size={24} />
            </Box>
          ) : rules.length === 0 ? (
            <Typography variant="body2" color="text.secondary">
              Keine abonnierbaren Nachrichten verfügbar.
            </Typography>
          ) : (
            <FormGroup>
              {rules.map((rule) => (
                <Box key={rule.id} sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>
                  <FormControlLabel
                    control={
                      <Switch
                        checked={!!rule.is_subscribed}
                        onChange={() => handleToggle(rule.id, !!rule.is_subscribed)}
                        size="small"
                      />
                    }
                    label={rule.name}
                    sx={{ flex: 1 }}
                  />
                  <Chip
                    label={MESSAGE_TYPE_LABELS[rule.message_type] ?? rule.message_type}
                    size="small"
                    variant="outlined"
                  />
                </Box>
              ))}
            </FormGroup>
          )}
        </CardContent>
      </Card>
    </Grid>
  );
}

function Settings() {
  const { themeMode, setThemeMode } = useThemeMode();
  const queryClient = useQueryClient();
  const { showInfo } = useNotification();
  const { user } = useAuth();
  const navigate = useNavigate();
  const { hasPermission } = usePermissionContext();

  const { data: preferences, isLoading: prefsLoading } = useQuery({
    queryKey: ['user-preferences'],
    queryFn: preferencesApi.get,
  });

  const mutation = useMutation({
    mutationFn: preferencesApi.update,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['user-preferences'] });
    },
  });

  const isWidgetVisible = (key: WidgetKey) => {
    return preferences?.widgets?.[key] !== false;
  };

  const toggleWidget = (key: WidgetKey) => {
    const current = preferences ?? {};
    const widgets = { ...(current.widgets ?? {}) };
    widgets[key] = !isWidgetVisible(key);
    mutation.mutate({ ...current, widgets });
  };

  // Menu ordering
  const menuOrder: string[] = (preferences?.menuOrder as string[] | undefined) ?? [];
  const visibleNavItems = ORDERABLE_NAV_ITEMS.filter(
    (item) => !item.permission || hasPermission(item.permission),
  );
  const orderedNavItems = [...visibleNavItems].sort((a, b) => {
    const aIdx = menuOrder.indexOf(a.path);
    const bIdx = menuOrder.indexOf(b.path);
    if (aIdx !== -1 && bIdx !== -1) return aIdx - bIdx;
    if (aIdx !== -1) return -1;
    if (bIdx !== -1) return 1;
    return 0;
  });

  const [localNavItems, setLocalNavItems] = useState(orderedNavItems);
  useEffect(() => {
    setLocalNavItems(orderedNavItems);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [visibleNavItems.map((i) => i.path).join(','), menuOrder.join(',')]);

  const navSensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
  );

  const handleNavDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    const oldIdx = localNavItems.findIndex((i) => i.path === active.id);
    const newIdx = localNavItems.findIndex((i) => i.path === over.id);
    if (oldIdx === -1 || newIdx === -1) return;
    const newItems = arrayMove(localNavItems, oldIdx, newIdx);
    setLocalNavItems(newItems);
    const current = preferences ?? {};
    mutation.mutate({ ...current, menuOrder: newItems.map((i) => i.path) });
  };

  const resetMenuOrder = () => {
    const current = preferences ?? {};
    const updated = { ...current };
    delete updated.menuOrder;
    mutation.mutate(updated);
  };

  // Nextcloud Talk connection
  const { data: ncData, isLoading: ncLoading } = useQuery({
    queryKey: ['nextcloud-talk-rooms'],
    queryFn: () => nextcloudApi.getRooms(),
    retry: 1,
  });

  const ncConnected = ncData?.connected ?? false;
  const ncLoginName = ncData?.loginName;

  const [isConnecting, setIsConnecting] = useState(false);
  const pollIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const popupRef = useRef<Window | null>(null);

  // Show one-time info snackbar when not connected
  useEffect(() => {
    if (!ncLoading && !ncConnected && !sessionStorage.getItem('nextcloud-talk-notified')) {
      sessionStorage.setItem('nextcloud-talk-notified', '1');
      showInfo('Nextcloud Talk ist nicht verbunden. Verbinde dich in den Einstellungen.');
    }
  }, [ncLoading, ncConnected, showInfo]);

  const stopPolling = useCallback(() => {
    if (pollIntervalRef.current) {
      clearInterval(pollIntervalRef.current);
      pollIntervalRef.current = null;
    }
    if (popupRef.current && !popupRef.current.closed) {
      popupRef.current.close();
    }
    popupRef.current = null;
    setIsConnecting(false);
  }, []);

  useEffect(() => {
    return () => {
      if (pollIntervalRef.current) {
        clearInterval(pollIntervalRef.current);
      }
      if (popupRef.current && !popupRef.current.closed) {
        popupRef.current.close();
      }
    };
  }, []);

  const handleConnect = async () => {
    try {
      setIsConnecting(true);
      const { loginUrl, pollToken, pollEndpoint } = await nextcloudApi.connect();

      const popup = window.open(loginUrl, '_blank', 'width=600,height=700');
      popupRef.current = popup;

      const startTime = Date.now();

      pollIntervalRef.current = setInterval(async () => {
        if (Date.now() - startTime > POLL_TIMEOUT) {
          stopPolling();
          return;
        }

        if (popup && popup.closed) {
          stopPolling();
          return;
        }

        try {
          const result = await nextcloudApi.poll(pollToken, pollEndpoint);
          if (result.completed) {
            stopPolling();
            queryClient.invalidateQueries({ queryKey: ['nextcloud', 'connection'] });
            queryClient.invalidateQueries({ queryKey: ['nextcloud', 'rooms'] });
          }
        } catch {
          // Polling error — keep trying until timeout
        }
      }, POLL_INTERVAL);
    } catch {
      setIsConnecting(false);
    }
  };

  const handleDisconnect = async () => {
    try {
      await nextcloudApi.disconnect();
      queryClient.invalidateQueries({ queryKey: ['nextcloud-talk'] });
      queryClient.invalidateQueries({ queryKey: ['nextcloud-talk-rooms'] });
    } catch {
      // Disconnect failed silently
    }
  };

  return (
    <DashboardLayout>
      <Container maxWidth="lg">
        <Typography variant="h4" gutterBottom sx={{ mb: 4 }}>
          Einstellungen
        </Typography>

        <Grid container spacing={3}>
          {/* Widget Visibility */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Widgets color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Dashboard-Widgets</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                {prefsLoading ? (
                  <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
                    <CircularProgress size={24} />
                  </Box>
                ) : (
                  <FormGroup>
                    {WIDGETS.map((w) => (
                      <FormControlLabel
                        key={w.key}
                        control={
                          <Switch
                            checked={isWidgetVisible(w.key)}
                            onChange={() => toggleWidget(w.key)}
                            disabled={mutation.isPending}
                          />
                        }
                        label={w.label}
                      />
                    ))}
                  </FormGroup>
                )}
              </CardContent>
            </Card>
          </Grid>

          {/* Menu Ordering */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
                  <Box sx={{ display: 'flex', alignItems: 'center' }}>
                    <Sort color="primary" sx={{ mr: 2 }} />
                    <Typography variant="h6">Menü-Reihenfolge</Typography>
                  </Box>
                  <Button
                    size="small"
                    startIcon={<Restore />}
                    onClick={resetMenuOrder}
                    disabled={mutation.isPending || menuOrder.length === 0}
                  >
                    Zurücksetzen
                  </Button>
                </Box>
                <Divider sx={{ mb: 1 }} />
                {prefsLoading ? (
                  <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
                    <CircularProgress size={24} />
                  </Box>
                ) : (
                  <DndContext
                    sensors={navSensors}
                    collisionDetection={closestCenter}
                    onDragEnd={handleNavDragEnd}
                  >
                    <SortableContext
                      items={localNavItems.map((i) => i.path)}
                      strategy={verticalListSortingStrategy}
                    >
                      <List disablePadding>
                        {localNavItems.map((item) => (
                          <SortableNavItem key={item.path} id={item.path} text={item.text} />
                        ))}
                      </List>
                    </SortableContext>
                  </DndContext>
                )}
              </CardContent>
            </Card>
          </Grid>

          {/* Nextcloud Talk */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Forum color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Nextcloud Talk</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                {ncLoading ? (
                  <Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}>
                    <CircularProgress size={24} />
                  </Box>
                ) : ncConnected ? (
                  <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                      <Chip label="Verbunden" size="small" color="success" />
                      {ncLoginName && (
                        <Typography variant="body2" color="text.secondary">
                          als {ncLoginName}
                        </Typography>
                      )}
                    </Box>
                    <Button
                      variant="outlined"
                      color="error"
                      startIcon={<LinkOff />}
                      onClick={handleDisconnect}
                      size="small"
                    >
                      Verbindung trennen
                    </Button>
                  </Box>
                ) : (
                  <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                      <Chip label="Nicht verbunden" size="small" color="default" />
                    </Box>
                    {isConnecting ? (
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                        <CircularProgress size={20} />
                        <Typography variant="body2" color="text.secondary">
                          Warte auf Bestätigung...
                        </Typography>
                      </Box>
                    ) : (
                      <Button
                        variant="outlined"
                        startIcon={<Cloud />}
                        onClick={handleConnect}
                        size="small"
                      >
                        Mit Nextcloud verbinden
                      </Button>
                    )}
                  </Box>
                )}
              </CardContent>
            </Card>
          </Grid>

          {/* Mitgliedsprofil */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Person color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Mitgliedsprofil</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                  Persönliche Daten, Standesbuchnummer und weitere Profileinstellungen.
                </Typography>
                <Button
                  variant="outlined"
                  size="small"
                  startIcon={<OpenInNew />}
                  onClick={() => navigate(`/mitglieder/${user?.id}`)}
                  disabled={!user?.id}
                >
                  Zum Mitgliedsprofil
                </Button>
              </CardContent>
            </Card>
          </Grid>

          {/* Notification Settings */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Notifications color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Benachrichtigungen</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                <FormGroup>
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="E-Mail-Benachrichtigungen"
                  />
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="Einsatz-Alarme"
                  />
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="Wartungserinnerungen"
                  />
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="System-Benachrichtigungen"
                  />
                  <Typography variant="caption" color="text.secondary" sx={{ mt: 1 }}>
                    (Bald verfügbar)
                  </Typography>
                </FormGroup>
              </CardContent>
            </Card>
          </Grid>

          {/* Display Settings */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Palette color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Anzeigeoptionen</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                <FormGroup>
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="Kompakte Ansicht"
                  />
                  <FormControlLabel
                    control={<Switch checked={false} disabled />}
                    label="Animationen"
                  />
                  <Typography variant="caption" color="text.secondary" sx={{ mt: 1 }}>
                    (Bald verfügbar)
                  </Typography>
                  <Box sx={{ mt: 1 }}>
                    <Typography variant="body2" sx={{ mb: 1 }}>
                      Farbschema
                    </Typography>
                    <ToggleButtonGroup
                      value={themeMode}
                      exclusive
                      onChange={(_e, value) => { if (value) setThemeMode(value); }}
                      size="small"
                    >
                      <ToggleButton value="system">
                        <SettingsBrightness fontSize="small" sx={{ mr: 0.5 }} />
                        System
                      </ToggleButton>
                      <ToggleButton value="light">
                        <LightMode fontSize="small" sx={{ mr: 0.5 }} />
                        Hell
                      </ToggleButton>
                      <ToggleButton value="dark">
                        <DarkMode fontSize="small" sx={{ mr: 0.5 }} />
                        Dunkel
                      </ToggleButton>
                    </ToggleButtonGroup>
                  </Box>
                </FormGroup>
              </CardContent>
            </Card>
          </Grid>

          {/* Language Settings */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <Language color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Sprache</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                <Typography variant="body2" color="text.secondary">
                  Aktuelle Sprache: Deutsch
                </Typography>
                <Typography variant="body2" color="text.secondary" sx={{ mt: 2 }}>
                  Kommende Features: Sprachauswahl, Datumsformat, Zeitzone
                </Typography>
              </CardContent>
            </Card>
          </Grid>

          {/* General Settings */}
          <Grid item xs={12} md={6}>
            <Card>
              <CardContent>
                <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
                  <SettingsIcon color="primary" sx={{ mr: 2 }} />
                  <Typography variant="h6">Allgemein</Typography>
                </Box>
                <Divider sx={{ mb: 2 }} />
                <Typography variant="body2" color="text.secondary">
                  Kommende Features: Dashboard-Layout, Standardansichten, Exporteinstellungen
                </Typography>
              </CardContent>
            </Card>
          </Grid>

          {/* Nachrichten-Abonnements */}
          {hasPermission('scheduled_messages:subscribe') && (
            <SubscriptionsCard />
          )}
        </Grid>
      </Container>
    </DashboardLayout>
  );
}

export default Settings;
