import { useState, useMemo, useEffect } from 'react';
import {
  Box, Typography, Paper, Button, IconButton, Chip,
  Table, TableBody, TableCell, TableHead, TableRow,
  Autocomplete, TextField, Alert, CircularProgress,
  Dialog, DialogTitle, DialogContent, DialogActions,
  LinearProgress,
} from '@mui/material';
import {
  ArrowBack,
  Add as AddIcon,
  ShoppingCart as ShoppingCartIcon,
} from '@mui/icons-material';
import { useParams, useNavigate } from 'react-router-dom';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import { PageBreadcrumbs } from '../components/common';
import { useNotification } from '../contexts/NotificationContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import { ausruestungsanfrageApi } from '../services/ausruestungsanfrage';
import { bestellungApi } from '../services/bestellung';
import { AUSRUESTUNG_STATUS_LABELS } from '../types/ausruestungsanfrage.types';
import type {
  AusruestungAnfrage,
  AusruestungAnfragePosition,
  CreateOrdersRequest,
} from '../types/ausruestungsanfrage.types';
import type { Lieferant } from '../types/bestellung.types';

// ── Helpers ──

function formatOrderId(r: AusruestungAnfrage): string {
  if (r.bestell_jahr && r.bestell_nummer) {
    return `${r.bestell_jahr}/${String(r.bestell_nummer).padStart(3, '0')}`;
  }
  return `#${r.id}`;
}

interface VendorAssignment {
  lieferantId: number;
  lieferantName: string;
}

interface VendorGroup {
  lieferantId: number;
  lieferantName: string;
  positionen: AusruestungAnfragePosition[];
}

// ══════════════════════════════════════════════════════════════════════════════
// Component
// ══════════════════════════════════════════════════════════════════════════════

export default function AusruestungsanfrageZuBestellung() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { showSuccess, showError } = useNotification();
  const { hasPermission } = usePermissionContext();

  const requestId = Number(id);
  const canManageVendors = hasPermission('bestellungen:manage_vendors');

  // ── Data ──
  const { data: detail, isLoading, isError } = useQuery({
    queryKey: ['ausruestungsanfrage', requestId],
    queryFn: () => ausruestungsanfrageApi.getRequest(requestId),
    enabled: !!requestId,
  });

  const { data: vendors = [] } = useQuery({
    queryKey: ['bestellung-vendors'],
    queryFn: () => bestellungApi.getVendors(),
  });

  const { data: catalogItems = [] } = useQuery({
    queryKey: ['ausruestungsanfrage', 'items-for-edit'],
    queryFn: () => ausruestungsanfrageApi.getItems({ aktiv: true }),
    staleTime: 5 * 60 * 1000,
  });

  const anfrage = detail?.anfrage;
  const positionen: AusruestungAnfragePosition[] = detail?.positionen ?? [];

  // ── State ──
  const [assignments, setAssignments] = useState<Record<number, VendorAssignment | null>>({});
  const [orderNames, setOrderNames] = useState<Record<number, string>>({});

  // New vendor dialog
  const [newVendorDialog, setNewVendorDialog] = useState(false);
  const [newVendorName, setNewVendorName] = useState('');
  const [newVendorKontakt, setNewVendorKontakt] = useState('');
  const [newVendorEmail, setNewVendorEmail] = useState('');
  const [newVendorTelefon, setNewVendorTelefon] = useState('');
  // Track which position triggered the new-vendor dialog
  const [newVendorTargetPosId, setNewVendorTargetPosId] = useState<number | null>(null);

  // ── Pre-populate vendor assignments from catalog items' preferred vendor ──
  useEffect(() => {
    if (positionen.length === 0 || catalogItems.length === 0 || vendors.length === 0) return;
    setAssignments(prev => {
      const next = { ...prev };
      let changed = false;
      positionen.forEach(pos => {
        // Don't overwrite existing manual assignments
        if (next[pos.id] != null) return;
        if (!pos.artikel_id) return;
        const artikel = catalogItems.find(a => a.id === pos.artikel_id);
        if (!artikel?.bevorzugter_lieferant_id) return;
        const vendor = vendors.find(v => v.id === artikel.bevorzugter_lieferant_id);
        if (!vendor) return;
        next[pos.id] = { lieferantId: vendor.id, lieferantName: vendor.name };
        changed = true;
      });
      return changed ? next : prev;
    });
  }, [positionen, catalogItems, vendors]);

  // ── Derived: vendor groups ──
  const vendorGroups: VendorGroup[] = useMemo(() => {
    const map = new Map<number, VendorGroup>();
    positionen.forEach(pos => {
      const a = assignments[pos.id];
      if (!a) return;
      if (!map.has(a.lieferantId)) {
        map.set(a.lieferantId, { lieferantId: a.lieferantId, lieferantName: a.lieferantName, positionen: [] });
      }
      map.get(a.lieferantId)!.positionen.push(pos);
    });
    return [...map.values()];
  }, [assignments, positionen]);

  // ── Auto-fill order names when a new vendor group appears ──
  useEffect(() => {
    if (!anfrage) return;
    const label = formatOrderId(anfrage);
    vendorGroups.forEach(g => {
      setOrderNames(prev => {
        if (prev[g.lieferantId]) return prev;
        return { ...prev, [g.lieferantId]: `Anfrage ${label} – ${g.lieferantName}` };
      });
    });
  }, [vendorGroups, anfrage]);

  // ── Derived: progress ──
  const assignedCount = positionen.filter(p => assignments[p.id] != null).length;
  const skippedCount = positionen.length - assignedCount;

  // ── Mutations ──
  const createOrdersMut = useMutation({
    mutationFn: (payload: CreateOrdersRequest) =>
      ausruestungsanfrageApi.createOrders(requestId, payload),
    onSuccess: (result) => {
      showSuccess(`${result.created_bestellungen.length} Bestellung(en) erfolgreich erstellt`);
      queryClient.invalidateQueries({ queryKey: ['ausruestungsanfrage', requestId] });
      navigate('/bestellungen');
    },
    onError: () => showError('Bestellungen konnten nicht erstellt werden'),
  });

  const createVendorMut = useMutation({
    mutationFn: (data: { name: string; kontakt_name?: string; email?: string; telefon?: string }) =>
      bestellungApi.createVendor(data),
    onSuccess: (newVendor: Lieferant) => {
      queryClient.invalidateQueries({ queryKey: ['bestellung-vendors'] });
      // Auto-assign to the position that triggered the dialog
      if (newVendorTargetPosId != null) {
        setAssignments(prev => ({
          ...prev,
          [newVendorTargetPosId]: { lieferantId: newVendor.id, lieferantName: newVendor.name },
        }));
      }
      setNewVendorDialog(false);
      setNewVendorName('');
      setNewVendorKontakt('');
      setNewVendorEmail('');
      setNewVendorTelefon('');
      setNewVendorTargetPosId(null);
      showSuccess(`Lieferant "${newVendor.name}" erstellt`);
    },
    onError: () => showError('Lieferant konnte nicht erstellt werden'),
  });

  // ── Handlers ──
  const canSubmit = vendorGroups.length > 0 && !createOrdersMut.isPending;

  const handleSubmit = () => {
    if (!canSubmit) return;
    const orders = vendorGroups.map(g => ({
      lieferant_id: g.lieferantId,
      bezeichnung: orderNames[g.lieferantId] || `Anfrage – ${g.lieferantName}`,
      positionen: g.positionen.map(p => ({
        position_id: p.id,
        bezeichnung: p.bezeichnung,
        menge: p.menge,
        einheit: p.einheit,
        notizen: p.notizen,
        artikel_id: p.artikel_id,
        spezifikationen: p.eigenschaften?.length
          ? p.eigenschaften.map(e => `${e.eigenschaft_name}: ${e.wert}`)
          : undefined,
      })),
    }));
    createOrdersMut.mutate({ orders });
  };

  const handleCreateVendor = () => {
    if (!newVendorName.trim()) return;
    createVendorMut.mutate({
      name: newVendorName.trim(),
      kontakt_name: newVendorKontakt.trim() || undefined,
      email: newVendorEmail.trim() || undefined,
      telefon: newVendorTelefon.trim() || undefined,
    });
  };

  // ── Loading / error states ──
  if (isLoading) {
    return (
      <DashboardLayout>
        <Box sx={{ display: 'flex', justifyContent: 'center', mt: 8 }}>
          <CircularProgress />
        </Box>
      </DashboardLayout>
    );
  }

  if (isError || !anfrage) {
    return (
      <DashboardLayout>
        <Alert severity="error" sx={{ m: 3 }}>Anfrage konnte nicht geladen werden.</Alert>
      </DashboardLayout>
    );
  }

  // ── Render ──
  return (
    <DashboardLayout>
      <Box sx={{ maxWidth: 960, mx: 'auto', px: 2, py: 3 }}>
        <PageBreadcrumbs items={[
          { label: 'Ausrüstungsanfragen', href: '/ausruestungsanfrage' },
          { label: anfrage.bezeichnung || `Anfrage ${formatOrderId(anfrage)}`, href: `/ausruestungsanfrage/${requestId}` },
          { label: 'Bestellen' },
        ]} />

        {/* ── Header ── */}
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 3 }}>
          <IconButton onClick={() => navigate(`/ausruestungsanfrage/${requestId}`)} size="small">
            <ArrowBack />
          </IconButton>
          <Box sx={{ flex: 1 }}>
            <Typography variant="h5" fontWeight={600}>
              Bestellungen erstellen
            </Typography>
            <Typography variant="body2" color="text.secondary">
              {anfrage.bezeichnung || `Anfrage ${formatOrderId(anfrage)}`}
              {' · '}
              <Chip
                label={AUSRUESTUNG_STATUS_LABELS[anfrage.status]}
                size="small"
                sx={{ height: 18, fontSize: 11 }}
              />
            </Typography>
          </Box>
          <Chip
            label={`${assignedCount} / ${positionen.length} zugewiesen`}
            color={assignedCount > 0 ? 'primary' : 'default'}
            variant="outlined"
          />
        </Box>

        {/* ── Progress bar ── */}
        <LinearProgress
          variant="determinate"
          value={positionen.length > 0 ? (assignedCount / positionen.length) * 100 : 0}
          sx={{ mb: 3, borderRadius: 2, height: 6 }}
          color="primary"
        />

        {/* ── Items table ── */}
        <Paper sx={{ mb: 3 }}>
          <Box sx={{ px: 2, py: 1.5, borderBottom: '1px solid', borderColor: 'divider' }}>
            <Typography variant="subtitle2">Lieferanten zuweisen</Typography>
          </Box>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell>Artikel</TableCell>
                <TableCell align="right" sx={{ width: 80 }}>Menge</TableCell>
                <TableCell sx={{ width: 320 }}>Lieferant</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {positionen.map(pos => {
                const assignment = assignments[pos.id];
                const selectedVendor = assignment
                  ? vendors.find(v => v.id === assignment.lieferantId) ?? null
                  : null;
                return (
                  <TableRow key={pos.id}>
                    <TableCell>
                      <Typography variant="body2" fontWeight={500}>{pos.bezeichnung}</Typography>
                      {pos.notizen && (
                        <Typography variant="caption" color="text.secondary">{pos.notizen}</Typography>
                      )}
                    </TableCell>
                    <TableCell align="right">
                      <Typography variant="body2">{pos.menge} {pos.einheit ?? 'Stk'}</Typography>
                    </TableCell>
                    <TableCell>
                      <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                        <Autocomplete<Lieferant>
                          size="small"
                          sx={{ flex: 1 }}
                          options={vendors}
                          getOptionLabel={o => o.name}
                          value={selectedVendor}
                          onChange={(_, v) => {
                            setAssignments(prev => ({
                              ...prev,
                              [pos.id]: v ? { lieferantId: v.id, lieferantName: v.name } : null,
                            }));
                          }}
                          renderInput={params => (
                            <TextField
                              {...params}
                              placeholder="Lieferant wählen…"
                              size="small"
                            />
                          )}
                          isOptionEqualToValue={(o, v) => o.id === v.id}
                        />
                        {canManageVendors && (
                          <IconButton
                            size="small"
                            title="Neuen Lieferanten anlegen"
                            onClick={() => {
                              setNewVendorTargetPosId(pos.id);
                              setNewVendorDialog(true);
                            }}
                          >
                            <AddIcon fontSize="small" />
                          </IconButton>
                        )}
                      </Box>
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </Paper>

        {/* ── Preview section ── */}
        {vendorGroups.length > 0 && (
          <Box sx={{ mb: 3 }}>
            <Typography variant="subtitle2" sx={{ mb: 1.5 }}>
              Vorschau — {vendorGroups.length} Bestellung{vendorGroups.length !== 1 ? 'en' : ''} werden erstellt
            </Typography>
            <Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}>
              {vendorGroups.map(g => (
                <Paper
                  key={g.lieferantId}
                  variant="outlined"
                  sx={{ p: 2, minWidth: 240, flex: '1 1 240px', maxWidth: 360 }}
                >
                  <Typography variant="subtitle2" color="primary" sx={{ mb: 0.5 }}>
                    {g.lieferantName}
                  </Typography>
                  <Typography variant="caption" color="text.secondary" sx={{ mb: 1.5, display: 'block' }}>
                    {g.positionen.length} Artikel
                  </Typography>
                  <Box sx={{ mb: 1.5 }}>
                    {g.positionen.map(p => (
                      <Typography key={p.id} variant="body2" sx={{ py: 0.25 }}>
                        · {p.bezeichnung} ×{p.menge}
                      </Typography>
                    ))}
                  </Box>
                  <TextField
                    size="small"
                    fullWidth
                    label="Bezeichnung der Bestellung"
                    value={orderNames[g.lieferantId] ?? ''}
                    onChange={e =>
                      setOrderNames(prev => ({ ...prev, [g.lieferantId]: e.target.value }))
                    }
                  />
                </Paper>
              ))}
            </Box>
          </Box>
        )}

        {/* ── Bottom action bar ── */}
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, justifyContent: 'flex-end' }}>
          {skippedCount > 0 && assignedCount > 0 && (
            <Alert severity="info" sx={{ flex: 1, py: 0.5 }}>
              {skippedCount} Artikel {skippedCount === 1 ? 'ist' : 'sind'} auf Lager und {skippedCount === 1 ? 'wird' : 'werden'} nicht bestellt.
            </Alert>
          )}
          {assignedCount === 0 && positionen.length > 0 && (
            <Alert severity="info" sx={{ flex: 1, py: 0.5 }}>
              Mindestens einem Artikel einen Lieferanten zuweisen, um Bestellungen zu erstellen.
            </Alert>
          )}
          <Button
            variant="contained"
            size="large"
            startIcon={<ShoppingCartIcon />}
            disabled={!canSubmit}
            onClick={handleSubmit}
          >
            {createOrdersMut.isPending ? 'Erstelle…' : `${vendorGroups.length || ''} Bestellung${vendorGroups.length !== 1 ? 'en' : ''} erstellen`}
          </Button>
        </Box>
      </Box>

      {/* ── New vendor dialog ── */}
      <Dialog
        open={newVendorDialog}
        onClose={() => { setNewVendorDialog(false); setNewVendorTargetPosId(null); }}
        maxWidth="sm"
        fullWidth
      >
        <DialogTitle>Neuen Lieferanten anlegen</DialogTitle>
        <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: '20px !important' }}>
          <TextField
            label="Name *"
            value={newVendorName}
            onChange={e => setNewVendorName(e.target.value)}
            autoFocus
            fullWidth
          />
          <TextField
            label="Kontaktperson"
            value={newVendorKontakt}
            onChange={e => setNewVendorKontakt(e.target.value)}
            fullWidth
          />
          <TextField
            label="E-Mail"
            value={newVendorEmail}
            onChange={e => setNewVendorEmail(e.target.value)}
            fullWidth
            type="email"
          />
          <TextField
            label="Telefon"
            value={newVendorTelefon}
            onChange={e => setNewVendorTelefon(e.target.value)}
            fullWidth
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => { setNewVendorDialog(false); setNewVendorTargetPosId(null); }}>
            Abbrechen
          </Button>
          <Button
            variant="contained"
            disabled={!newVendorName.trim() || createVendorMut.isPending}
            onClick={handleCreateVendor}
          >
            Anlegen
          </Button>
        </DialogActions>
      </Dialog>
    </DashboardLayout>
  );
}
