import { useState, useEffect } from 'react';
import {
  Box,
  Typography,
  Button,
  TextField,
  Select,
  MenuItem,
  FormControl,
  FormControlLabel,
  InputLabel,
  CircularProgress,
  Alert,
  Switch,
  Chip,
  Stack,
  Card,
  CardContent,
  CardHeader,
  Container,
  Grid,
} from '@mui/material';
import {
  CheckCircle,
  Warning,
  Block,
} from '@mui/icons-material';
import { useQuery } from '@tanstack/react-query';
import { useParams, useNavigate } from 'react-router-dom';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import { PageHeader } from '../components/templates';
import ServiceModePage from '../components/shared/ServiceModePage';
import GermanDateField from '../components/shared/GermanDateField';
import { usePermissionContext } from '../contexts/PermissionContext';
import { useNotification } from '../contexts/NotificationContext';
import { bookingApi, fetchVehicles, kategorieApi } from '../services/bookings';
import type { CreateBuchungInput, BuchungsArt } from '../types/booking.types';
import { BUCHUNGS_ART_LABELS } from '../types/booking.types';

const EMPTY_FORM: CreateBuchungInput = {
  fahrzeugId: '',
  titel: '',
  beschreibung: '',
  beginn: '',
  ende: '',
  buchungsArt: 'intern',
  kontaktPerson: '',
  kontaktTelefon: '',
  ganztaegig: false,
};

function BookingFormPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { isFeatureEnabled } = usePermissionContext();
  const notification = useNotification();
  const isEdit = Boolean(id);

  const [form, setForm] = useState<CreateBuchungInput>({ ...EMPTY_FORM });
  const [overrideOutOfService, setOverrideOutOfService] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [availability, setAvailability] = useState<{
    available: boolean;
    reason?: string;
    ausserDienstBis?: string;
  } | null>(null);

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

  // Fetch active categories
  const { data: kategorien = [] } = useQuery({
    queryKey: ['buchungskategorien'],
    queryFn: kategorieApi.getActive,
  });

  // Fetch existing booking for edit mode
  const { data: existingBooking, isLoading: loadingBooking } = useQuery({
    queryKey: ['booking', id],
    queryFn: () => bookingApi.getById(id!),
    enabled: !!id,
  });

  // Pre-fill form when editing
  useEffect(() => {
    if (existingBooking) {
      const beginn = existingBooking.ganztaegig
        ? existingBooking.beginn.split('T')[0]
        : existingBooking.beginn.slice(0, 16); // yyyy-MM-ddTHH:mm
      const ende = existingBooking.ganztaegig
        ? existingBooking.ende.split('T')[0]
        : existingBooking.ende.slice(0, 16);
      setForm({
        fahrzeugId: existingBooking.fahrzeug_id,
        titel: existingBooking.titel,
        beschreibung: existingBooking.beschreibung || '',
        beginn: existingBooking.ganztaegig ? `${beginn}T00:00` : beginn,
        ende: existingBooking.ganztaegig ? `${ende}T23:59` : ende,
        buchungsArt: existingBooking.buchungs_art,
        kontaktPerson: existingBooking.kontakt_person || '',
        kontaktTelefon: existingBooking.kontakt_telefon || '',
        ganztaegig: existingBooking.ganztaegig || false,
      });
    }
  }, [existingBooking]);

  // Check availability whenever relevant form fields change
  useEffect(() => {
    if (!form.fahrzeugId || !form.beginn || !form.ende) {
      setAvailability(null);
      return;
    }
    const beginn = new Date(form.beginn);
    const ende = new Date(form.ende);
    if (isNaN(beginn.getTime()) || isNaN(ende.getTime()) || ende <= beginn) {
      setAvailability(null);
      return;
    }
    let cancelled = false;
    const timer = setTimeout(() => {
      bookingApi
        .checkAvailability(form.fahrzeugId, beginn, ende, id)
        .then((result) => {
          if (!cancelled) setAvailability(result);
        })
        .catch(() => {
          if (!cancelled) setAvailability(null);
        });
    }, 300);
    return () => {
      cancelled = true;
      clearTimeout(timer);
    };
  }, [form.fahrzeugId, form.beginn, form.ende, id]);

  // Determine if the selected category is "extern"-like (show contact fields)
  const selectedKategorie = kategorien.find(
    (k) => k.bezeichnung.toLowerCase() === form.buchungsArt
  );
  const isExtern =
    form.buchungsArt === 'extern' ||
    selectedKategorie?.bezeichnung.toLowerCase() === 'extern';

  // Date validity check
  const formBeginnDate = form.beginn ? new Date(form.beginn) : null;
  const formEndeDate = form.ende ? new Date(form.ende) : null;
  const formDatesValid = !!(
    formBeginnDate &&
    formEndeDate &&
    !isNaN(formBeginnDate.getTime()) &&
    !isNaN(formEndeDate.getTime()) &&
    formEndeDate > formBeginnDate
  );

  const handleSave = async () => {
    setSaving(true);
    setError(null);
    try {
      const beginnDate = new Date(form.beginn);
      const endeDate = new Date(form.ende);
      if (isNaN(beginnDate.getTime()) || isNaN(endeDate.getTime())) {
        setError('Ungültiges Datum. Bitte Beginn und Ende prüfen.');
        setSaving(false);
        return;
      }
      if (endeDate <= beginnDate) {
        setError('Ende muss nach dem Beginn liegen.');
        setSaving(false);
        return;
      }
      const payload: CreateBuchungInput = {
        ...form,
        beginn: beginnDate.toISOString(),
        ende: endeDate.toISOString(),
        ganztaegig: form.ganztaegig || false,
      };
      if (isEdit && id) {
        await bookingApi.update(id, payload);
        notification.showSuccess('Buchung aktualisiert');
      } else {
        await bookingApi.create({
          ...payload,
          ignoreOutOfService: overrideOutOfService,
        } as any);
        notification.showSuccess('Buchung erstellt');
      }
      navigate('/fahrzeugbuchungen');
    } catch (e: unknown) {
      try {
        const axiosError = e as {
          response?: {
            status?: number;
            data?: { message?: string; reason?: string };
          };
          message?: string;
        };
        if (axiosError?.response?.status === 409) {
          const reason = axiosError?.response?.data?.reason;
          if (reason === 'out_of_service') {
            setError(
              axiosError?.response?.data?.message ||
                'Fahrzeug ist im gewählten Zeitraum außer Dienst'
            );
          } else {
            setError(
              axiosError?.response?.data?.message ||
                'Fahrzeug ist im gewählten Zeitraum bereits gebucht'
            );
          }
        } else {
          setError(
            axiosError?.response?.data?.message ||
              axiosError?.message ||
              'Fehler beim Speichern'
          );
        }
      } catch {
        setError(e instanceof Error ? e.message : 'Fehler beim Speichern');
      }
    } finally {
      setSaving(false);
    }
  };

  if (isEdit && loadingBooking) {
    return (
      <DashboardLayout>
        <Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}>
          <CircularProgress />
        </Box>
      </DashboardLayout>
    );
  }

  return (
    <DashboardLayout>
      {!isFeatureEnabled('fahrzeugbuchungen') ? (
        <ServiceModePage message="Fahrzeugbuchungen befinden sich aktuell im Wartungsmodus." />
      ) : (
      <Container maxWidth="md" sx={{ py: 3 }}>
        <PageHeader
          title={isEdit ? 'Buchung bearbeiten' : 'Neue Buchung'}
          backTo="/fahrzeugbuchungen"
        />

        {error && (
          <Alert severity="error" sx={{ mb: 2 }}>
            {error}
          </Alert>
        )}

        <Stack spacing={3}>
          {/* Card 1: Fahrzeug & Zeitraum */}
          <Card variant="outlined">
            <CardHeader title="Fahrzeug & Zeitraum" titleTypographyProps={{ variant: 'subtitle1', fontWeight: 600 }} />
            <CardContent>
              <Stack spacing={2}>
                <FormControl fullWidth size="small" required>
                  <InputLabel>Fahrzeug</InputLabel>
                  <Select
                    value={form.fahrzeugId}
                    onChange={(e) =>
                      setForm((f) => ({ ...f, fahrzeugId: e.target.value }))
                    }
                    label="Fahrzeug"
                  >
                    {vehicles.map((v) => (
                      <MenuItem key={v.id} value={v.id}>
                        {v.bezeichnung}
                        {v.amtliches_kennzeichen
                          ? ` (${v.amtliches_kennzeichen})`
                          : ''}
                      </MenuItem>
                    ))}
                  </Select>
                </FormControl>

                <Grid container spacing={2}>
                  <Grid item xs={12} sm={6}>
                    <GermanDateField
                      fullWidth
                      size="small"
                      label="Beginn"
                      required
                      mode={form.ganztaegig ? 'date' : 'datetime'}
                      value={
                        form.ganztaegig
                          ? form.beginn?.split('T')[0] || ''
                          : form.beginn
                      }
                      onChange={(iso) => {
                        if (form.ganztaegig) {
                          setForm((f) => ({
                            ...f,
                            beginn: `${iso}T00:00`,
                          }));
                        } else {
                          setForm((f) => ({ ...f, beginn: iso }));
                        }
                      }}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <GermanDateField
                      fullWidth
                      size="small"
                      label="Ende"
                      required
                      mode={form.ganztaegig ? 'date' : 'datetime'}
                      value={
                        form.ganztaegig ? form.ende?.split('T')[0] || '' : form.ende
                      }
                      onChange={(iso) => {
                        if (form.ganztaegig) {
                          setForm((f) => ({
                            ...f,
                            ende: `${iso}T23:59`,
                          }));
                        } else {
                          setForm((f) => ({ ...f, ende: iso }));
                        }
                      }}
                    />
                  </Grid>
                </Grid>

                <FormControlLabel
                  control={
                    <Switch
                      checked={form.ganztaegig || false}
                      onChange={(e) => {
                        const checked = e.target.checked;
                        setForm((f) => {
                          if (checked && f.beginn) {
                            const dateStr = f.beginn.split('T')[0];
                            return {
                              ...f,
                              ganztaegig: true,
                              beginn: `${dateStr}T00:00`,
                              ende: f.ende
                                ? `${f.ende.split('T')[0]}T23:59`
                                : `${dateStr}T23:59`,
                            };
                          }
                          return { ...f, ganztaegig: checked };
                        });
                      }}
                    />
                  }
                  label="Ganztägig"
                />

                {/* Availability indicator */}
                {form.fahrzeugId && form.beginn && form.ende ? (
                  !formDatesValid ? (
                    <Typography
                      variant="body2"
                      color="error"
                      sx={{ fontSize: '0.75rem' }}
                    >
                      Ende muss nach dem Beginn liegen
                    </Typography>
                  ) : (
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                      {availability === null ? (
                        <Box
                          sx={{ display: 'flex', alignItems: 'center', gap: 1 }}
                        >
                          <CircularProgress size={16} />
                          <Typography variant="body2" color="text.secondary">
                            Verfügbarkeit wird geprüft...
                          </Typography>
                        </Box>
                      ) : availability.available ? (
                        <Chip
                          icon={<CheckCircle />}
                          label="Fahrzeug verfügbar"
                          color="success"
                          size="small"
                        />
                      ) : availability.reason === 'out_of_service' ? (
                        <Box>
                          <Chip
                            icon={<Block />}
                            label={
                              availability.ausserDienstBis
                                ? `Außer Dienst bis ${new Date(availability.ausserDienstBis).toLocaleDateString('de-DE')} (geschätzt)`
                                : 'Fahrzeug ist außer Dienst'
                            }
                            color="error"
                            size="small"
                          />
                          <FormControlLabel
                            control={
                              <Switch
                                checked={overrideOutOfService}
                                onChange={(e) =>
                                  setOverrideOutOfService(e.target.checked)
                                }
                                color="warning"
                                size="small"
                              />
                            }
                            label={
                              <Typography variant="body2" color="warning.main">
                                Trotz Außer-Dienst-Status buchen
                              </Typography>
                            }
                            sx={{ mt: 0.5 }}
                          />
                        </Box>
                      ) : (
                        <Chip
                          icon={<Warning />}
                          label="Konflikt: bereits gebucht"
                          color="error"
                          size="small"
                        />
                      )}
                    </Box>
                  )
                ) : (
                  <Typography
                    variant="body2"
                    color="text.secondary"
                    sx={{ fontSize: '0.75rem' }}
                  >
                    Wähle Fahrzeug und Zeitraum für Verfügbarkeitsprüfung
                  </Typography>
                )}
              </Stack>
            </CardContent>
          </Card>

          {/* Card 2: Details */}
          <Card variant="outlined">
            <CardHeader title="Details" titleTypographyProps={{ variant: 'subtitle1', fontWeight: 600 }} />
            <CardContent>
              <Stack spacing={2}>
                <TextField
                  fullWidth
                  size="small"
                  label="Titel"
                  required
                  value={form.titel}
                  onChange={(e) =>
                    setForm((f) => ({ ...f, titel: e.target.value }))
                  }
                />

                <TextField
                  fullWidth
                  size="small"
                  label="Beschreibung"
                  multiline
                  rows={2}
                  value={form.beschreibung || ''}
                  onChange={(e) =>
                    setForm((f) => ({ ...f, beschreibung: e.target.value }))
                  }
                />

                <FormControl fullWidth size="small">
                  <InputLabel>Kategorie</InputLabel>
                  <Select
                    value={form.buchungsArt}
                    onChange={(e) =>
                      setForm((f) => ({
                        ...f,
                        buchungsArt: e.target.value as BuchungsArt,
                      }))
                    }
                    label="Kategorie"
                  >
                    {kategorien.length > 0
                      ? kategorien.map((k) => (
                          <MenuItem key={k.id} value={k.bezeichnung.toLowerCase()}>
                            <Box
                              sx={{ display: 'flex', alignItems: 'center', gap: 1 }}
                            >
                              <Box
                                sx={{
                                  width: 12,
                                  height: 12,
                                  borderRadius: '50%',
                                  bgcolor: k.farbe,
                                  flexShrink: 0,
                                }}
                              />
                              {k.bezeichnung}
                            </Box>
                          </MenuItem>
                        ))
                      : (
                          Object.entries(BUCHUNGS_ART_LABELS) as [
                            BuchungsArt,
                            string,
                          ][]
                        ).map(([art, label]) => (
                          <MenuItem key={art} value={art}>
                            {label}
                          </MenuItem>
                        ))}
                  </Select>
                </FormControl>

                {isExtern && (
                  <>
                    <TextField
                      fullWidth
                      size="small"
                      label="Kontaktperson"
                      value={form.kontaktPerson || ''}
                      onChange={(e) =>
                        setForm((f) => ({ ...f, kontaktPerson: e.target.value }))
                      }
                    />
                    <TextField
                      fullWidth
                      size="small"
                      label="Kontakttelefon"
                      value={form.kontaktTelefon || ''}
                      onChange={(e) =>
                        setForm((f) => ({
                          ...f,
                          kontaktTelefon: e.target.value,
                        }))
                      }
                    />
                  </>
                )}
              </Stack>
            </CardContent>
          </Card>

          {/* Actions */}
          <Box sx={{ display: 'flex', gap: 2, justifyContent: 'flex-end' }}>
            <Button
              variant="outlined"
              onClick={() => navigate('/fahrzeugbuchungen')}
            >
              Abbrechen
            </Button>
            <Button
              variant="contained"
              onClick={handleSave}
              disabled={
                saving ||
                !form.titel ||
                !form.fahrzeugId ||
                !form.beginn ||
                !form.ende
              }
            >
              {saving ? <CircularProgress size={20} /> : 'Speichern'}
            </Button>
          </Box>
        </Stack>
      </Container>
      )}
    </DashboardLayout>
  );
}

export default BookingFormPage;
