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,
  Stack,
  Tooltip,
} from '@mui/material';
import {
  Add,
  IosShare,
  ContentCopy,
  Cancel,
  Edit,
  EventBusy,
  Settings,
} from '@mui/icons-material';
import { useQuery, 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');

  // ── 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: 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');
    }
  };

  // ── 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>
          <Box sx={{ display: 'flex', gap: 1 }}>
            {canManage && (
              <Tooltip title="Einstellungen">
                <IconButton onClick={() => navigate('/admin/settings?tab=1&subtab=fahrzeugbuchungen')}>
                  <Settings />
                </IconButton>
              </Tooltip>
            )}
            <Button startIcon={<IosShare />} onClick={handleIcalOpen} variant="outlined" size="small">
              iCal abonnieren
            </Button>
          </Box>
        </Box>

        {/* ── Buchungen ─────────────────────────────────────────────── */}
        <>
          {/* 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>
              ))}
          </>

        {/* ── FAB ── */}
        {canCreate && (
          <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>

      </Container>
    </DashboardLayout>
  );
}

export default FahrzeugBuchungen;
