import { useState } from 'react';
import {
  Box,
  Container,
  Typography,
  Paper,
  Card,
  CardContent,
  Button,
  IconButton,
  TextField,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  CircularProgress,
  Alert,
  Chip,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Tab,
  Tabs,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Checkbox,
  Stack,
  Tooltip,
} from '@mui/material';
import {
  Add,
  IosShare,
  ContentCopy,
  Cancel,
  Edit,
  Delete,
  Save,
  Close,
  EventBusy,
} from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { format, parseISO } from 'date-fns';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import ChatAwareFab from '../components/shared/ChatAwareFab';
import GermanDateField from '../components/shared/GermanDateField';
import ServiceModePage from '../components/shared/ServiceModePage';
import { useAuth } from '../contexts/AuthContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import { useNotification } from '../contexts/NotificationContext';
import { bookingApi, fetchVehicles, kategorieApi } from '../services/bookings';
import type {
  BuchungsArt,
  BuchungsKategorie,
} from '../types/booking.types';
import { BUCHUNGS_ART_LABELS, BUCHUNGS_ART_COLORS } from '../types/booking.types';

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function formatBookingDate(beginn: string, ende: string, ganztaegig: boolean): string {
  try {
    const b = parseISO(beginn);
    const e = parseISO(ende);
    if (ganztaegig) {
      return `${format(b, 'dd.MM.yyyy')} – ${format(e, 'dd.MM.yyyy')} (Ganztägig)`;
    }
    return `${format(b, 'dd.MM.yyyy HH:mm')} – ${format(e, 'dd.MM.yyyy HH:mm')}`;
  } catch {
    return `${beginn} – ${ende}`;
  }
}

function getCategoryColor(buchungsArt: BuchungsArt, kategorien: BuchungsKategorie[]): string {
  const kat = kategorien.find((k) => k.bezeichnung.toLowerCase() === buchungsArt);
  if (kat) return kat.farbe;
  return BUCHUNGS_ART_COLORS[buchungsArt] || '#757575';
}

function getCategoryLabel(buchungsArt: BuchungsArt, kategorien: BuchungsKategorie[]): string {
  const kat = kategorien.find((k) => k.bezeichnung.toLowerCase() === buchungsArt);
  if (kat) return kat.bezeichnung;
  return BUCHUNGS_ART_LABELS[buchungsArt] || buchungsArt;
}

// ---------------------------------------------------------------------------
// Main Page
// ---------------------------------------------------------------------------

function FahrzeugBuchungen() {
  const { user } = useAuth();
  const { hasPermission, isFeatureEnabled } = usePermissionContext();
  const notification = useNotification();
  const navigate = useNavigate();
  const queryClient = useQueryClient();

  const canCreate = hasPermission('fahrzeugbuchungen:create');
  const canManage = hasPermission('fahrzeugbuchungen:manage');

  const [tabIndex, setTabIndex] = useState(0);

  // ── Filters ────────────────────────────────────────────────────────────────
  const today = new Date();
  const defaultFrom = format(today, 'yyyy-MM-dd');
  const defaultTo = format(new Date(today.getTime() + 90 * 86400000), 'yyyy-MM-dd');
  const [filterFrom, setFilterFrom] = useState(defaultFrom);
  const [filterTo, setFilterTo] = useState(defaultTo);
  const [filterVehicle, setFilterVehicle] = useState('');
  const [filterKategorie, setFilterKategorie] = useState('');

  // ── Data ───────────────────────────────────────────────────────────────────
  const { data: vehicles = [] } = useQuery({
    queryKey: ['vehicles'],
    queryFn: fetchVehicles,
  });

  const { data: kategorien = [] } = useQuery({
    queryKey: ['buchungskategorien-all'],
    queryFn: kategorieApi.getAll,
  });

  const { data: activeKategorien = [] } = useQuery({
    queryKey: ['buchungskategorien'],
    queryFn: kategorieApi.getActive,
  });

  const fromDate = filterFrom ? new Date(`${filterFrom}T00:00:00`) : new Date();
  const toDate = filterTo ? new Date(`${filterTo}T23:59:59`) : new Date(Date.now() + 90 * 86400000);

  const {
    data: calendarData,
    isLoading,
    isError,
    error: loadError,
  } = useQuery({
    queryKey: ['bookings-range', filterFrom, filterTo, filterVehicle],
    queryFn: () =>
      bookingApi.getCalendarRange(
        fromDate,
        toDate,
        filterVehicle || undefined
      ),
  });

  const bookings = (calendarData?.bookings || [])
    .filter((b) => !b.abgesagt)
    .filter((b) => !filterKategorie || b.buchungs_art === filterKategorie)
    .sort((a, b) => new Date(a.beginn).getTime() - new Date(b.beginn).getTime());

  // ── Cancel ─────────────────────────────────────────────────────────────────
  const [cancelId, setCancelId] = useState<string | null>(null);
  const [cancelGrund, setCancelGrund] = useState('');
  const [cancelLoading, setCancelLoading] = useState(false);

  const handleCancel = async () => {
    if (!cancelId) return;
    setCancelLoading(true);
    try {
      await bookingApi.cancel(cancelId, cancelGrund);
      notification.showSuccess('Buchung storniert');
      setCancelId(null);
      setCancelGrund('');
      queryClient.invalidateQueries({ queryKey: ['bookings-range'] });
    } catch (e: unknown) {
      const axiosErr = e as { response?: { data?: { message?: string } }; message?: string };
      notification.showError(
        axiosErr?.response?.data?.message || (e instanceof Error ? e.message : 'Fehler beim Stornieren')
      );
    } finally {
      setCancelLoading(false);
    }
  };

  // ── iCal ───────────────────────────────────────────────────────────────────
  const [icalOpen, setIcalOpen] = useState(false);
  const [icalUrl, setIcalUrl] = useState('');

  const handleIcalOpen = async () => {
    try {
      const { subscribeUrl } = await bookingApi.getCalendarToken();
      setIcalUrl(subscribeUrl);
      setIcalOpen(true);
    } catch (e: unknown) {
      notification.showError(e instanceof Error ? e.message : 'Fehler beim Laden des Tokens');
    }
  };

  // ── Einstellungen: Categories management ───────────────────────────────────
  const [editRowId, setEditRowId] = useState<number | null>(null);
  const [editRowData, setEditRowData] = useState<Partial<BuchungsKategorie>>({});
  const [newKatDialog, setNewKatDialog] = useState(false);
  const [newKatForm, setNewKatForm] = useState({ bezeichnung: '', farbe: '#1976d2' });

  const createKatMutation = useMutation({
    mutationFn: (data: Omit<BuchungsKategorie, 'id'>) => kategorieApi.create(data),
    onSuccess: () => {
      notification.showSuccess('Kategorie erstellt');
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien-all'] });
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien'] });
      setNewKatDialog(false);
      setNewKatForm({ bezeichnung: '', farbe: '#1976d2' });
    },
    onError: () => notification.showError('Fehler beim Erstellen'),
  });

  const updateKatMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<BuchungsKategorie> }) =>
      kategorieApi.update(id, data),
    onSuccess: () => {
      notification.showSuccess('Kategorie aktualisiert');
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien-all'] });
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien'] });
      setEditRowId(null);
    },
    onError: () => notification.showError('Fehler beim Aktualisieren'),
  });

  const deleteKatMutation = useMutation({
    mutationFn: (id: number) => kategorieApi.delete(id),
    onSuccess: () => {
      notification.showSuccess('Kategorie deaktiviert');
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien-all'] });
      queryClient.invalidateQueries({ queryKey: ['buchungskategorien'] });
    },
    onError: () => notification.showError('Fehler beim Löschen'),
  });

  // ── Render ─────────────────────────────────────────────────────────────────
  if (!isFeatureEnabled('fahrzeugbuchungen')) {
    return <ServiceModePage message="Fahrzeugbuchungen befinden sich aktuell im Wartungsmodus." />;
  }

  return (
    <DashboardLayout>
      <Container maxWidth="xl" sx={{ py: 3 }}>
        {/* Header */}
        <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
          <Typography variant="h4" fontWeight={700}>
            Fahrzeugbuchungen
          </Typography>
          <Button startIcon={<IosShare />} onClick={handleIcalOpen} variant="outlined" size="small">
            iCal abonnieren
          </Button>
        </Box>

        {/* Tabs */}
        <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>
          <Tabs value={tabIndex} onChange={(_, v) => setTabIndex(v)}>
            <Tab label="Buchungen" />
            {canManage && <Tab label="Einstellungen" />}
          </Tabs>
        </Box>

        {/* ── Tab 0: Buchungen ─────────────────────────────────────────────── */}
        {tabIndex === 0 && (
          <>
            {/* Filters */}
            <Paper sx={{ p: 2, mb: 2 }}>
              <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} alignItems="center">
                <GermanDateField
                  size="small"
                  label="Von"
                  value={filterFrom}
                  onChange={(iso) => setFilterFrom(iso)}
                  sx={{ minWidth: 160 }}
                />
                <GermanDateField
                  size="small"
                  label="Bis"
                  value={filterTo}
                  onChange={(iso) => setFilterTo(iso)}
                  sx={{ minWidth: 160 }}
                />
                <FormControl size="small" sx={{ minWidth: 180 }}>
                  <InputLabel>Fahrzeug</InputLabel>
                  <Select
                    value={filterVehicle}
                    onChange={(e) => setFilterVehicle(e.target.value)}
                    label="Fahrzeug"
                  >
                    <MenuItem value="">Alle Fahrzeuge</MenuItem>
                    {vehicles.map((v) => (
                      <MenuItem key={v.id} value={v.id}>
                        {v.bezeichnung}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
                <FormControl size="small" sx={{ minWidth: 180 }}>
                  <InputLabel>Kategorie</InputLabel>
                  <Select
                    value={filterKategorie}
                    onChange={(e) => setFilterKategorie(e.target.value)}
                    label="Kategorie"
                  >
                    <MenuItem value="">Alle Kategorien</MenuItem>
                    {activeKategorien.map((k) => (
                      <MenuItem key={k.id} value={k.bezeichnung.toLowerCase()}>
                        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                          <Box
                            sx={{
                              width: 10,
                              height: 10,
                              borderRadius: '50%',
                              bgcolor: k.farbe,
                            }}
                          />
                          {k.bezeichnung}
                        </Box>
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>
              </Stack>
            </Paper>

            {/* Loading */}
            {isLoading && (
              <Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>
                <CircularProgress />
              </Box>
            )}

            {/* Error */}
            {isError && (
              <Alert severity="error" sx={{ mb: 2 }}>
                {loadError instanceof Error ? loadError.message : 'Fehler beim Laden'}
              </Alert>
            )}

            {/* Bookings list */}
            {!isLoading && !isError && bookings.length === 0 && (
              <Paper sx={{ p: 4, textAlign: 'center' }}>
                <EventBusy sx={{ fontSize: 48, color: 'text.secondary', mb: 1 }} />
                <Typography variant="body1" color="text.secondary">
                  Keine Buchungen vorhanden
                </Typography>
              </Paper>
            )}

            {!isLoading &&
              !isError &&
              bookings.map((booking) => (
                <Card key={booking.id} sx={{ mb: 1.5 }}>
                  <CardContent sx={{ pb: '12px !important' }}>
                    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                      <Box sx={{ flex: 1 }}>
                        <Typography variant="subtitle1" fontWeight={700}>
                          {booking.titel}
                        </Typography>
                        <Typography variant="body2" color="text.secondary">
                          {booking.fahrzeug_name}
                          {booking.fahrzeug_kennzeichen
                            ? ` (${booking.fahrzeug_kennzeichen})`
                            : ''}
                        </Typography>
                        <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
                          {formatBookingDate(booking.beginn, booking.ende, booking.ganztaegig)}
                        </Typography>
                        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mt: 1 }}>
                          <Chip
                            label={getCategoryLabel(booking.buchungs_art, activeKategorien)}
                            size="small"
                            sx={{
                              bgcolor: getCategoryColor(booking.buchungs_art, activeKategorien),
                              color: 'white',
                            }}
                          />
                          {booking.gebucht_von_name && (
                            <Typography variant="caption" color="text.secondary">
                              von {booking.gebucht_von_name}
                            </Typography>
                          )}
                        </Box>
                      </Box>
                      <Box sx={{ display: 'flex', gap: 0.5 }}>
                        {(canManage || booking.gebucht_von === user?.id) && (
                          <Tooltip title="Bearbeiten">
                            <IconButton
                              size="small"
                              onClick={() => navigate(`/fahrzeugbuchungen/${booking.id}`)}
                            >
                              <Edit fontSize="small" />
                            </IconButton>
                          </Tooltip>
                        )}
                        {(canManage || booking.gebucht_von === user?.id) && (
                          <Tooltip title="Stornieren">
                            <IconButton
                              size="small"
                              color="error"
                              onClick={() => {
                                setCancelId(booking.id);
                                setCancelGrund('');
                              }}
                            >
                              <Cancel fontSize="small" />
                            </IconButton>
                          </Tooltip>
                        )}
                      </Box>
                    </Box>
                  </CardContent>
                </Card>
              ))}
          </>
        )}

        {/* ── Tab 1: Einstellungen ─────────────────────────────────────────── */}
        {tabIndex === 1 && canManage && (
          <Paper sx={{ p: 2 }}>
            <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
              <Typography variant="h6">Buchungskategorien</Typography>
              <Button
                startIcon={<Add />}
                variant="contained"
                size="small"
                onClick={() => setNewKatDialog(true)}
              >
                Neue Kategorie
              </Button>
            </Box>

            <TableContainer>
              <Table size="small">
                <TableHead>
                  <TableRow>
                    <TableCell>Bezeichnung</TableCell>
                    <TableCell>Farbe</TableCell>
                    <TableCell>Sortierung</TableCell>
                    <TableCell>Aktiv</TableCell>
                    <TableCell align="right">Aktionen</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {kategorien.map((kat) => {
                    const isEditing = editRowId === kat.id;
                    return (
                      <TableRow key={kat.id}>
                        <TableCell>
                          {isEditing ? (
                            <TextField
                              size="small"
                              value={editRowData.bezeichnung ?? kat.bezeichnung}
                              onChange={(e) =>
                                setEditRowData((d) => ({ ...d, bezeichnung: e.target.value }))
                              }
                            />
                          ) : (
                            kat.bezeichnung
                          )}
                        </TableCell>
                        <TableCell>
                          {isEditing ? (
                            <input
                              type="color"
                              value={editRowData.farbe ?? kat.farbe}
                              onChange={(e) =>
                                setEditRowData((d) => ({ ...d, farbe: e.target.value }))
                              }
                              style={{ width: 40, height: 28, border: 'none', cursor: 'pointer' }}
                            />
                          ) : (
                            <Box
                              sx={{
                                width: 24,
                                height: 24,
                                borderRadius: 1,
                                bgcolor: kat.farbe,
                                border: '1px solid',
                                borderColor: 'divider',
                              }}
                            />
                          )}
                        </TableCell>
                        <TableCell>
                          {isEditing ? (
                            <TextField
                              size="small"
                              type="number"
                              value={editRowData.sort_order ?? kat.sort_order}
                              onChange={(e) =>
                                setEditRowData((d) => ({
                                  ...d,
                                  sort_order: parseInt(e.target.value) || 0,
                                }))
                              }
                              sx={{ width: 80 }}
                            />
                          ) : (
                            kat.sort_order
                          )}
                        </TableCell>
                        <TableCell>
                          {isEditing ? (
                            <Checkbox
                              checked={editRowData.aktiv ?? kat.aktiv}
                              onChange={(e) =>
                                setEditRowData((d) => ({ ...d, aktiv: e.target.checked }))
                              }
                            />
                          ) : (
                            <Checkbox checked={kat.aktiv} disabled />
                          )}
                        </TableCell>
                        <TableCell align="right">
                          {isEditing ? (
                            <Stack direction="row" spacing={0.5} justifyContent="flex-end">
                              <IconButton
                                size="small"
                                color="primary"
                                onClick={() =>
                                  updateKatMutation.mutate({ id: kat.id, data: editRowData })
                                }
                              >
                                <Save fontSize="small" />
                              </IconButton>
                              <IconButton
                                size="small"
                                onClick={() => {
                                  setEditRowId(null);
                                  setEditRowData({});
                                }}
                              >
                                <Close fontSize="small" />
                              </IconButton>
                            </Stack>
                          ) : (
                            <Stack direction="row" spacing={0.5} justifyContent="flex-end">
                              <IconButton
                                size="small"
                                onClick={() => {
                                  setEditRowId(kat.id);
                                  setEditRowData({
                                    bezeichnung: kat.bezeichnung,
                                    farbe: kat.farbe,
                                    sort_order: kat.sort_order,
                                    aktiv: kat.aktiv,
                                  });
                                }}
                              >
                                <Edit fontSize="small" />
                              </IconButton>
                              <IconButton
                                size="small"
                                color="error"
                                onClick={() => deleteKatMutation.mutate(kat.id)}
                              >
                                <Delete fontSize="small" />
                              </IconButton>
                            </Stack>
                          )}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                  {kategorien.length === 0 && (
                    <TableRow>
                      <TableCell colSpan={5} align="center">
                        <Typography variant="body2" color="text.secondary" sx={{ py: 2 }}>
                          Keine Kategorien vorhanden
                        </Typography>
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            </TableContainer>
          </Paper>
        )}

        {/* ── FAB ── */}
        {canCreate && tabIndex === 0 && (
          <ChatAwareFab
            color="primary"
            aria-label="Buchung erstellen"
            onClick={() => navigate('/fahrzeugbuchungen/neu')}
          >
            <Add />
          </ChatAwareFab>
        )}

        {/* ── Cancel dialog ── */}
        <Dialog
          open={Boolean(cancelId)}
          onClose={() => setCancelId(null)}
          maxWidth="xs"
          fullWidth
        >
          <DialogTitle>Buchung stornieren</DialogTitle>
          <DialogContent>
            <TextField
              fullWidth
              multiline
              rows={3}
              label="Stornierungsgrund"
              value={cancelGrund}
              onChange={(e) => setCancelGrund(e.target.value)}
              sx={{ mt: 1 }}
              helperText={`${cancelGrund.length}/1000 (min. 5 Zeichen)`}
              inputProps={{ maxLength: 1000 }}
            />
          </DialogContent>
          <DialogActions>
            <Button onClick={() => setCancelId(null)} disabled={cancelLoading}>
              Abbrechen
            </Button>
            <Button
              variant="contained"
              color="error"
              onClick={handleCancel}
              disabled={cancelGrund.length < 5 || cancelLoading}
              startIcon={cancelLoading ? <CircularProgress size={16} /> : undefined}
            >
              Stornieren
            </Button>
          </DialogActions>
        </Dialog>

        {/* ── iCal dialog ── */}
        <Dialog open={icalOpen} onClose={() => setIcalOpen(false)} maxWidth="sm" fullWidth>
          <DialogTitle>Kalender abonnieren</DialogTitle>
          <DialogContent>
            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
              Abonniere den Fahrzeugbuchungskalender in deiner Kalenderanwendung. Kopiere die URL und
              füge sie als neuen Kalender (per URL) in Apple Kalender, Google Kalender oder Outlook
              ein.
            </Typography>
            <TextField
              fullWidth
              value={icalUrl}
              InputProps={{
                readOnly: true,
                endAdornment: (
                  <IconButton
                    onClick={() => {
                      navigator.clipboard.writeText(icalUrl);
                      notification.showSuccess('URL kopiert!');
                    }}
                  >
                    <ContentCopy />
                  </IconButton>
                ),
              }}
            />
          </DialogContent>
          <DialogActions>
            <Button onClick={() => setIcalOpen(false)}>Schließen</Button>
          </DialogActions>
        </Dialog>

        {/* ── New category dialog ── */}
        <Dialog
          open={newKatDialog}
          onClose={() => setNewKatDialog(false)}
          maxWidth="xs"
          fullWidth
        >
          <DialogTitle>Neue Kategorie</DialogTitle>
          <DialogContent>
            <Stack spacing={2} sx={{ mt: 1 }}>
              <TextField
                fullWidth
                size="small"
                label="Bezeichnung"
                required
                value={newKatForm.bezeichnung}
                onChange={(e) =>
                  setNewKatForm((f) => ({ ...f, bezeichnung: e.target.value }))
                }
              />
              <Box>
                <Typography variant="body2" sx={{ mb: 0.5 }}>
                  Farbe
                </Typography>
                <input
                  type="color"
                  value={newKatForm.farbe}
                  onChange={(e) => setNewKatForm((f) => ({ ...f, farbe: e.target.value }))}
                  style={{ width: 60, height: 36, border: 'none', cursor: 'pointer' }}
                />
              </Box>
            </Stack>
          </DialogContent>
          <DialogActions>
            <Button onClick={() => setNewKatDialog(false)}>Abbrechen</Button>
            <Button
              variant="contained"
              onClick={() =>
                createKatMutation.mutate({
                  bezeichnung: newKatForm.bezeichnung,
                  farbe: newKatForm.farbe,
                  aktiv: true,
                  sort_order: kategorien.length,
                })
              }
              disabled={!newKatForm.bezeichnung || createKatMutation.isPending}
            >
              Erstellen
            </Button>
          </DialogActions>
        </Dialog>
      </Container>
    </DashboardLayout>
  );
}

export default FahrzeugBuchungen;
