import React, { useState, useEffect } from "react";
import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  Box,
  Typography,
  TextField,
  IconButton,
  List,
  ListItem,
  Checkbox,
  FormControlLabel,
  Alert,
  CircularProgress,
  Chip,
  Paper,
  InputAdornment,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  FormHelperText,
} from "@mui/material";
import {
  Add,
  Delete,
  AttachFile,
  Warning,
  CheckCircle,
  Close,
  Link,
  Star,
  StarBorder,
} from "@mui/icons-material";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import Tooltip from "@mui/material/Tooltip";
import { useApplicationStore } from "../../store/applicationStore";

interface ComparisonOffer {
  id?: number;
  supplier_name: string;
  amount: number;
  description?: string;
  url?: string;
  attachment_id?: number;
  is_preferred: boolean;
}

interface ComparisonOffersDialogProps {
  open: boolean;
  onClose: () => void;
  paId: string;
  paKey?: string;
  costPositionIndex: number;
  costPositionName: string;
  costPositionAmount: number;
  attachments: Array<{
    id: number;
    filename: string;
  }>;
  isAdmin?: boolean;
  readOnly?: boolean;
}

const ComparisonOffersDialog: React.FC<ComparisonOffersDialogProps> = ({
  open,
  onClose,
  paId,
  paKey,
  costPositionIndex,
  costPositionName,
  costPositionAmount,
  attachments,
  isAdmin = false,
  readOnly = false,
}) => {
  const [offers, setOffers] = useState<ComparisonOffer[]>([]);
  const [noOffersRequired, setNoOffersRequired] = useState(false);
  const [justification, setJustification] = useState("");
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [newOffer, setNewOffer] = useState<ComparisonOffer>({
    supplier_name: "",
    amount: 0,
    description: "",
    url: "",
    is_preferred: false,
  });
  const [amountInput, setAmountInput] = useState("");

  const { masterKey } = useApplicationStore();

  // Load existing offers and justification
  useEffect(() => {
    if (open) {
      loadOffers();
      // Reset form when dialog opens
      setNewOffer({
        supplier_name: "",
        amount: 0,
        description: "",
        url: "",
        is_preferred: false,
      });
      setAmountInput("");
    }
  }, [open, costPositionIndex]);

  const loadOffers = async () => {
    setLoading(true);
    setError(null);
    try {
      const headers: HeadersInit = {};
      if (isAdmin && masterKey) {
        headers["X-MASTER-KEY"] = masterKey;
      } else if (paKey) {
        headers["X-PA-KEY"] = paKey;
      }

      const response = await fetch(
        `/api/applications/${paId}/costs/${costPositionIndex}/offers`,
        { headers },
      );

      if (!response.ok) {
        if (response.status === 404) {
          // Cost position might not exist in backend data
          console.warn(
            `Cost position ${costPositionIndex} not found in backend`,
          );
          setOffers([]);
          setNoOffersRequired(false);
          setJustification("");
          return;
        }
        throw new Error("Failed to load offers");
      }

      const data = await response.json();
      setOffers(
        data.offers.map((offer: any) => ({
          ...offer,
          is_preferred: offer.is_preferred || false,
        })) || [],
      );
      setNoOffersRequired(data.no_offers_required || false);
      setJustification(data.justification || "");
    } catch (err) {
      setError("Fehler beim Laden der Angebote");
      console.error("Error loading offers:", err);
    } finally {
      setLoading(false);
    }
  };

  const handleAddOffer = async () => {
    if (!newOffer.supplier_name || newOffer.amount <= 0) {
      setError("Bitte geben Sie einen Anbieter und einen gültigen Betrag ein");
      return;
    }

    // Check for duplicate supplier
    const duplicateSupplier = offers.find(
      (offer) =>
        offer.supplier_name.toLowerCase() ===
        newOffer.supplier_name.toLowerCase(),
    );
    if (duplicateSupplier) {
      setError(
        `Ein Angebot von "${newOffer.supplier_name}" existiert bereits für diese Kostenposition`,
      );
      return;
    }

    // Auto-prepend https:// if URL doesn't have protocol
    let finalUrl = newOffer.url;
    if (
      finalUrl &&
      !finalUrl.startsWith("http://") &&
      !finalUrl.startsWith("https://")
    ) {
      finalUrl = "https://" + finalUrl;
    }

    // Validate URL format if provided
    if (finalUrl && !isValidUrl(finalUrl)) {
      setError(
        "Bitte geben Sie eine gültige URL ein (z.B. beispiel.de oder https://beispiel.de)",
      );
      return;
    }

    // Validate that either URL or attachment is provided
    if (!newOffer.url && !newOffer.attachment_id) {
      setError(
        "Bitte geben Sie entweder eine URL oder verknüpfen Sie einen Anhang",
      );
      return;
    }

    setSaving(true);
    setError(null);
    try {
      const headers: HeadersInit = {
        "Content-Type": "application/json",
      };
      if (isAdmin && masterKey) {
        headers["X-MASTER-KEY"] = masterKey;
      } else if (paKey) {
        headers["X-PA-KEY"] = paKey;
      }

      const response = await fetch(
        `/api/applications/${paId}/costs/${costPositionIndex}/offers`,
        {
          method: "POST",
          headers,
          body: JSON.stringify({
            ...newOffer,
            url: finalUrl || undefined,
          }),
        },
      );

      if (!response.ok) {
        if (response.status === 409 || response.status === 400) {
          const errorData = await response.json();
          if (errorData.detail?.includes("Duplicate entry")) {
            setError(
              `Ein Angebot von "${newOffer.supplier_name}" existiert bereits für diese Kostenposition`,
            );
          } else {
            setError(errorData.detail || "Fehler beim Hinzufügen des Angebots");
          }
          return;
        }
        if (response.status === 404) {
          setError(
            "Diese Kostenposition existiert nicht in den gespeicherten Daten. Bitte speichern Sie den Antrag erneut.",
          );
          return;
        }
        throw new Error("Failed to add offer");
      }

      await loadOffers();
      setNewOffer({
        supplier_name: "",
        amount: 0,
        description: "",
        url: "",
        is_preferred: false,
      });
      setAmountInput("");
    } catch (err) {
      setError("Fehler beim Hinzufügen des Angebots");
      console.error("Error adding offer:", err);
    } finally {
      setSaving(false);
    }
  };

  const handleDeleteOffer = async (offerId: number) => {
    setSaving(true);
    setError(null);
    try {
      const headers: HeadersInit = {};
      if (isAdmin && masterKey) {
        headers["X-MASTER-KEY"] = masterKey;
      } else if (paKey) {
        headers["X-PA-KEY"] = paKey;
      }

      const response = await fetch(
        `/api/applications/${paId}/costs/${costPositionIndex}/offers/${offerId}`,
        {
          method: "DELETE",
          headers,
        },
      );

      if (!response.ok) {
        throw new Error("Failed to delete offer");
      }

      await loadOffers();
    } catch (err) {
      setError("Fehler beim Löschen des Angebots");
      console.error("Error deleting offer:", err);
    } finally {
      setSaving(false);
    }
  };

  const handleSetPreferred = (offerId: number | undefined) => {
    // Update local state to mark the preferred offer
    const updatedOffers = offers.map((offer) => ({
      ...offer,
      is_preferred: offer.id === offerId,
    }));
    setOffers(updatedOffers);
  };

  const handleSavePreferredOffer = async () => {
    setSaving(true);
    setError(null);
    try {
      const headers: HeadersInit = {
        "Content-Type": "application/json",
      };
      if (isAdmin && masterKey) {
        headers["X-MASTER-KEY"] = masterKey;
      } else if (paKey) {
        headers["X-PA-KEY"] = paKey;
      }

      // Save preferred offer selection
      const preferredOffer = offers.find((o) => o.is_preferred);
      if (preferredOffer && preferredOffer.id) {
        const response = await fetch(
          `/api/applications/${paId}/costs/${costPositionIndex}/offers/${preferredOffer.id}/preferred`,
          {
            method: "PUT",
            headers,
          },
        );

        if (!response.ok) {
          throw new Error("Failed to save preferred offer");
        }
      }

      onClose();
    } catch (err) {
      setError("Fehler beim Speichern des bevorzugten Angebots");
      console.error("Error saving preferred offer:", err);
    } finally {
      setSaving(false);
    }
  };

  const handleUpdateJustification = async () => {
    if (noOffersRequired && !justification.trim()) {
      setError("Bitte geben Sie eine Begründung ein");
      return;
    }

    setSaving(true);
    setError(null);
    try {
      const headers: HeadersInit = {
        "Content-Type": "application/json",
      };
      if (isAdmin && masterKey) {
        headers["X-MASTER-KEY"] = masterKey;
      } else if (paKey) {
        headers["X-PA-KEY"] = paKey;
      }

      const response = await fetch(
        `/api/applications/${paId}/costs/${costPositionIndex}/justification`,
        {
          method: "PUT",
          headers,
          body: JSON.stringify({
            no_offers_required: noOffersRequired,
            justification: noOffersRequired ? justification : null,
          }),
        },
      );

      if (!response.ok) {
        if (response.status === 404) {
          setError(
            "Diese Kostenposition existiert nicht in den gespeicherten Daten. Bitte speichern Sie den Antrag erneut.",
          );
          return;
        }
        throw new Error("Failed to update justification");
      }

      onClose();
    } catch (err) {
      setError("Fehler beim Speichern der Begründung");
      console.error("Error updating justification:", err);
    } finally {
      setSaving(false);
    }
  };

  const isValid = noOffersRequired
    ? justification.trim().length >= 10
    : offers.length >= 3;

  const hasPreferredOffer = offers.some((o) => o.is_preferred);

  const getAttachmentFilename = (attachmentId?: number) => {
    if (!attachmentId) return null;
    const attachment = attachments.find((a) => a.id === attachmentId);
    return attachment?.filename || null;
  };

  // URL validation helper
  const isValidUrl = (url: string): boolean => {
    try {
      const urlObj = new URL(url);
      return urlObj.protocol === "http:" || urlObj.protocol === "https:";
    } catch {
      return false;
    }
  };

  // Format amount for display
  const formatAmount = (value: string): string => {
    // Remove all non-digit and non-comma/period characters
    const cleaned = value.replace(/[^\d,.-]/g, "");
    // Replace comma with period for parsing
    return cleaned.replace(",", ".");
  };

  // Handle amount input change
  const handleAmountChange = (value: string) => {
    // Allow only numbers, comma, period, and minus sign
    const cleaned = value.replace(/[^\d,.-]/g, "");
    setAmountInput(cleaned);

    const formatted = formatAmount(cleaned);
    const parsed = parseFloat(formatted);
    if (!isNaN(parsed) && parsed > 0) {
      setNewOffer({ ...newOffer, amount: parsed });
    } else if (cleaned === "" || cleaned === "0") {
      setNewOffer({ ...newOffer, amount: 0 });
    }
  };

  return (
    <Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
      <DialogTitle>
        <Box display="flex" justifyContent="space-between" alignItems="center">
          <Box>
            <Typography variant="h6">Vergleichsangebote</Typography>
            <Typography variant="body2" color="text.secondary">
              {costPositionName} - {costPositionAmount.toFixed(2)} €
            </Typography>
          </Box>
          <IconButton size="small" onClick={onClose}>
            <Close />
          </IconButton>
        </Box>
      </DialogTitle>

      <DialogContent dividers>
        {error && (
          <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>
            {error}
          </Alert>
        )}

        {loading ? (
          <Box display="flex" justifyContent="center" py={3}>
            <CircularProgress />
          </Box>
        ) : (
          <>
            {/* Checkbox for no offers required */}
            {!readOnly && offers.length === 0 && (
              <FormControlLabel
                control={
                  <Checkbox
                    checked={noOffersRequired}
                    onChange={(e) => setNoOffersRequired(e.target.checked)}
                  />
                }
                label="Für diese Kostenposition sind keine Vergleichsangebote erforderlich"
                sx={{ mb: 2 }}
              />
            )}

            {/* Justification field */}
            {noOffersRequired && (
              <TextField
                fullWidth
                multiline
                rows={4}
                label="Begründung *"
                value={justification}
                onChange={(e) => setJustification(e.target.value)}
                disabled={readOnly}
                error={noOffersRequired && justification.trim().length < 10}
                helperText={
                  noOffersRequired && justification.trim().length < 10
                    ? "Bitte geben Sie eine ausführliche Begründung ein (mind. 10 Zeichen)"
                    : ""
                }
                sx={{ mb: 3 }}
              />
            )}

            {/* Offers list */}
            {!noOffersRequired && (
              <>
                <Typography
                  variant="subtitle1"
                  gutterBottom
                  color="text.primary"
                >
                  Vergleichsangebote ({offers.length}/3)
                  {offers.length < 3 && (
                    <Chip
                      size="small"
                      icon={<Warning />}
                      label="Mindestens 3 Angebote erforderlich"
                      color="warning"
                      sx={{ ml: 1 }}
                    />
                  )}
                </Typography>

                {offers.length > 0 ? (
                  <>
                    <Typography
                      variant="body2"
                      color="text.secondary"
                      sx={{ mb: 1 }}
                    >
                      Wählen Sie ein bevorzugtes Angebot durch Klick auf den
                      Stern:
                    </Typography>
                    <List>
                      {offers.map((offer, index) => (
                        <ListItem
                          key={offer.id || index}
                          disablePadding
                          sx={{ mb: 1 }}
                        >
                          <Paper
                            variant="outlined"
                            sx={{ width: "100%", p: 2 }}
                          >
                            <Box display="flex" justifyContent="space-between">
                              <Box
                                display="flex"
                                alignItems="flex-start"
                                gap={1}
                              >
                                <Radio
                                  checked={offer.is_preferred === true}
                                  onChange={() => handleSetPreferred(offer.id)}
                                  value={offer.id}
                                  disabled={readOnly || saving}
                                  size="small"
                                  icon={<StarBorder />}
                                  checkedIcon={<Star />}
                                  sx={{ mt: -0.5 }}
                                />
                                <Box flex={1}>
                                  <Typography
                                    variant="subtitle2"
                                    color="text.primary"
                                  >
                                    {offer.supplier_name}
                                  </Typography>
                                  <Typography variant="body1" color="primary">
                                    {offer.amount.toFixed(2)} €
                                  </Typography>
                                  {offer.description && (
                                    <Typography
                                      variant="body2"
                                      color="text.secondary"
                                    >
                                      {offer.description}
                                    </Typography>
                                  )}
                                  {offer.url && (
                                    <Box
                                      sx={{
                                        display: "flex",
                                        alignItems: "center",
                                        mt: 1,
                                        gap: 0.5,
                                      }}
                                    >
                                      <Link fontSize="small" color="primary" />
                                      <Typography
                                        variant="body2"
                                        color="primary"
                                        component="a"
                                        href={offer.url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        sx={{
                                          textDecoration: "none",
                                          "&:hover": {
                                            textDecoration: "underline",
                                          },
                                        }}
                                      >
                                        {offer.url}
                                      </Typography>
                                    </Box>
                                  )}
                                  {offer.attachment_id && (
                                    <Chip
                                      size="small"
                                      icon={<AttachFile />}
                                      label={
                                        getAttachmentFilename(
                                          offer.attachment_id,
                                        ) || "Anhang"
                                      }
                                      sx={{ mt: 1 }}
                                    />
                                  )}
                                </Box>
                              </Box>
                              {!readOnly && (
                                <Box>
                                  <IconButton
                                    color="error"
                                    onClick={() =>
                                      offer.id && handleDeleteOffer(offer.id)
                                    }
                                    disabled={saving}
                                  >
                                    <Delete />
                                  </IconButton>
                                </Box>
                              )}
                            </Box>
                          </Paper>
                        </ListItem>
                      ))}
                    </List>
                  </>
                ) : (
                  <Typography
                    color="text.secondary"
                    align="center"
                    sx={{ py: 2 }}
                  >
                    Noch keine Angebote hinzugefügt
                  </Typography>
                )}

                {/* Add new offer form */}
                {!readOnly && offers.length < 5 && (
                  <Paper variant="outlined" sx={{ p: 2, mt: 2 }}>
                    <Typography
                      variant="subtitle2"
                      gutterBottom
                      color="text.primary"
                    >
                      Neues Angebot hinzufügen
                    </Typography>
                    <Box display="flex" flexDirection="column" gap={2}>
                      <TextField
                        label="Anbieter / Name *"
                        value={newOffer.supplier_name}
                        onChange={(e) =>
                          setNewOffer({
                            ...newOffer,
                            supplier_name: e.target.value,
                          })
                        }
                        size="small"
                        fullWidth
                        error={offers.some(
                          (o) =>
                            o.supplier_name.toLowerCase() ===
                            newOffer.supplier_name.toLowerCase(),
                        )}
                        helperText={
                          offers.some(
                            (o) =>
                              o.supplier_name.toLowerCase() ===
                              newOffer.supplier_name.toLowerCase(),
                          )
                            ? "Dieser Anbieter existiert bereits"
                            : offers.length > 0
                              ? `Vorhandene Anbieter: ${offers
                                  .map((o) => o.supplier_name)
                                  .join(", ")}`
                              : ""
                        }
                      />
                      <TextField
                        label="Betrag *"
                        type="text"
                        value={amountInput}
                        onChange={(e) => handleAmountChange(e.target.value)}
                        size="small"
                        fullWidth
                        InputProps={{
                          endAdornment: (
                            <InputAdornment position="end">€</InputAdornment>
                          ),
                          inputProps: {
                            inputMode: "decimal",
                            pattern: "[0-9]*[,.]?[0-9]*",
                          },
                        }}
                        placeholder="0,00"
                        helperText={
                          amountInput !== "" && newOffer.amount <= 0
                            ? "Betrag muss größer als 0 sein"
                            : "Format: 123,45 oder 123.45"
                        }
                        error={amountInput !== "" && newOffer.amount <= 0}
                      />
                      <TextField
                        label="Beschreibung (optional)"
                        value={newOffer.description}
                        onChange={(e) =>
                          setNewOffer({
                            ...newOffer,
                            description: e.target.value,
                          })
                        }
                        size="small"
                        fullWidth
                        multiline
                        rows={2}
                      />
                      <TextField
                        label="URL (Pflicht wenn kein Anhang)"
                        value={newOffer.url}
                        onChange={(e) =>
                          setNewOffer({
                            ...newOffer,
                            url: e.target.value,
                          })
                        }
                        size="small"
                        fullWidth
                        type="url"
                        placeholder="beispiel.de/angebot.pdf"
                        helperText={
                          !newOffer.url && !newOffer.attachment_id
                            ? "URL oder Anhang erforderlich"
                            : newOffer.url && !newOffer.url.includes(".")
                              ? "Ungültige URL"
                              : "https:// wird automatisch hinzugefügt"
                        }
                        error={
                          (!newOffer.url && !newOffer.attachment_id) ||
                          (newOffer.url !== "" && !newOffer.url.includes("."))
                        }
                      />
                      <FormControl size="small" fullWidth>
                        <InputLabel>
                          Anhang verknüpfen (Pflicht wenn keine URL)
                        </InputLabel>
                        <Select
                          value={newOffer.attachment_id || ""}
                          onChange={(e) =>
                            setNewOffer({
                              ...newOffer,
                              attachment_id: e.target.value as number,
                            })
                          }
                          label="Anhang verknüpfen (Pflicht wenn keine URL)"
                          disabled={attachments.length === 0}
                        >
                          <MenuItem value="">
                            {attachments.length === 0
                              ? "Keine Anhänge vorhanden"
                              : "Kein Anhang"}
                          </MenuItem>
                          {attachments.map((att) => (
                            <MenuItem key={att.id} value={att.id}>
                              {att.filename}
                            </MenuItem>
                          ))}
                        </Select>
                        {attachments.length === 0 && (
                          <FormHelperText>
                            Laden Sie zuerst Anhänge hoch, um sie mit Angeboten
                            zu verknüpfen
                          </FormHelperText>
                        )}
                      </FormControl>
                      <Button
                        variant="contained"
                        startIcon={<Add />}
                        onClick={handleAddOffer}
                        disabled={
                          saving ||
                          !newOffer.supplier_name ||
                          !newOffer.amount ||
                          (!newOffer.url && !newOffer.attachment_id)
                        }
                      >
                        Angebot hinzufügen
                      </Button>
                    </Box>
                  </Paper>
                )}
              </>
            )}
          </>
        )}
      </DialogContent>

      <DialogActions>
        <Button onClick={onClose} disabled={saving}>
          Abbrechen
        </Button>
        {!readOnly && (
          <Button
            variant="contained"
            onClick={
              offers.length > 0
                ? handleSavePreferredOffer
                : handleUpdateJustification
            }
            disabled={
              saving || (offers.length > 0 ? !hasPreferredOffer : !isValid)
            }
            startIcon={
              (offers.length > 0 ? hasPreferredOffer : isValid) ? (
                <CheckCircle />
              ) : (
                <Warning />
              )
            }
          >
            Speichern
          </Button>
        )}
      </DialogActions>
    </Dialog>
  );
};

export default ComparisonOffersDialog;
