import { useTranslation } from "react-i18next";
import { useState, useEffect } from "react";
import * as React from "react";
import Cookies from "js-cookie";
import {
  Sheet,
  Input,
  Button,
  Checkbox,
  Chip,
  IconButton,
  Alert,
  Typography,
  FormControl,
  FormLabel,
  ButtonGroup,
  CircularProgress,
} from "@mui/joy";
import { submitFormData } from "../utils/api/form";
import type { FormData, Message } from "../config/interfaces.config";
import PersonIcon from "@mui/icons-material/Person";
import QrCodeIcon from "@mui/icons-material/QrCode";
import TranslateIcon from "@mui/icons-material/Translate";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { confirmUser, fetchUsers } from "../utils/api/users";
import { QRcodeModal } from "../components/modals/QR-CodeModal";
import { SelectUserModal } from "../components/modals/SelectUserModal";

const PAYMENT_METHODS = ["bar", "paypal", "andere"] as const;
const PAYMENT_LABELS: Record<string, string> = {
  bar: "Cash",
  paypal: "PayPal",
  andere: "Transfer",
};

const DEFAULT_FORM: FormData = {
  firstName: "",
  lastName: "",
  email: "",
  phoneNumber: "",
  tickets: 1,
  companyName: "",
  cmpFirstName: "",
  cpmLastName: "",
  cpmEmail: "",
  cpmPhoneNumber: "",
  street: "",
  postalCode: "",
  paymentMethod: "",
};

// ─── Field component lives OUTSIDE MainForm so React doesn't treat it as a
// new component type on every render, which would cause inputs to lose focus.
const Field = ({
  label,
  name,
  type = "text",
  required = true,
  formData,
  onChange,
}: {
  label: string;
  name: keyof FormData;
  type?: string;
  required?: boolean;
  formData: FormData;
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}) => (
  <FormControl required={required}>
    <FormLabel>{label}</FormLabel>
    <Input
      name={name}
      type={type}
      value={formData[name] as string}
      onChange={onChange}
      variant="soft"
      sx={{ borderRadius: "10px" }}
    />
  </FormControl>
);

export const MainForm = () => {
  const { t, i18n } = useTranslation();
  const queryClient = useQueryClient();

  const [invoice, setInvoice] = useState(false);
  const [msg, setMsg] = useState<Message | null>(null);
  const [selectedUser, setSelectedUser] = useState<string | null>(null);
  const [formData, setFormData] = useState<FormData>(DEFAULT_FORM);
  const [showSelectUser, setShowSelectUser] = useState(false);
  const [QRmodal, setQRmodal] = useState(false);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  useEffect(() => {
    const savedUser = Cookies.get("selectedUser");
    if (savedUser) {
      setSelectedUser(savedUser);
    } else {
      setMsg({
        type: "warning",
        headline: t("set-username-headline"),
        text: t("set-username-text"),
      });
    }
  }, []);

  const { data: usernameData, isLoading: usernameDataIsLoading } = useQuery({
    queryKey: ["users"],
    queryFn: fetchUsers,
  });

  const { data: userData } = useQuery({
    queryKey: ["user", selectedUser],
    enabled: !!selectedUser,
    queryFn: () => confirmUser(selectedUser),
  });

  const { mutate: mutateForm, isPending: mutateFormIsPending } = useMutation({
    mutationFn: () => submitFormData(formData, selectedUser),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
      document.location.href = `/success?id=${nextID}&tickets=${formData.tickets}`;
    },
    onError: () => {
      queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
      setMsg({
        type: "danger",
        headline: t("error"),
        text: t("form-submission-failed"),
      });
    },
  });

  // Setting the nextID after a user is selected
  const nextID = userData?.nextID ?? "N/A";

  const handleUserSelection = (username: string | null) => {
    if (username == null || username == "") {
      return;
    }

    setSelectedUser(username);
  };

  const changeTranslation = () => {
    const clientLng = i18n.language;

    if (clientLng === "en") {
      i18n.changeLanguage("de");
      Cookies.set("language", "de");
    } else if (clientLng === "de") {
      i18n.changeLanguage("en");
      Cookies.set("language", "en");
    } else {
      setMsg({
        type: "danger",
        headline: "Error",
        text: "Cannot change langugage.",
      });
    }
  };

  // Shorthand so we don't repeat formData + onChange on every Field usage
  const fieldProps = { formData, onChange: handleChange };

  return (
    <>
      <SelectUserModal
        showSelectUser={showSelectUser}
        setShowSelectUser={setShowSelectUser}
        usernameData={usernameData}
        usernameDataIsLoading={usernameDataIsLoading}
        selectedUser={selectedUser}
        handleUserSelection={handleUserSelection}
      />

      <QRcodeModal setQRmodal={setQRmodal} QRmodal={QRmodal} />

      <div className="min-h-screen w-full flex items-center justify-center from-slate-100 to-blue-50 p-4">
        <Sheet
          variant="plain"
          className="w-full"
          sx={{
            position: "relative",
            maxWidth: 460,
            borderRadius: "24px",
            p: { xs: "1.5rem", sm: "2rem" },
            boxShadow: "0 24px 64px -12px rgba(0,0,0,0.18)",
            background: "#fff",
          }}
        >
          <ButtonGroup
            color="primary"
            disabled={false}
            size="lg"
            spacing={1}
            variant="soft"
          >
            <IconButton onClick={() => setShowSelectUser(true)}>
              <PersonIcon />
            </IconButton>
            <IconButton onClick={() => setQRmodal(true)}>
              <QrCodeIcon />
            </IconButton>
            {/* Language toggle */}
            <IconButton onClick={changeTranslation}>
              <TranslateIcon />
            </IconButton>
            <Typography
              level="title-sm"
              textColor="var(--joy-palette-success-plainColor)"
              sx={{
                fontFamily: "monospace",
                opacity: "100%",
                alignSelf: "center",
              }}
            >
              {`${t("greeting")} ${userData?.fullname ?? t("loading")}`}
            </Typography>
          </ButtonGroup>

          <form
            onSubmit={(e) => {
              e.preventDefault();
              mutateForm();
            }}
            className="flex flex-col gap-4"
          >
            {/* Next ID badge */}
            <Chip
              size="lg"
              variant="solid"
              color="neutral"
              sx={{
                alignSelf: "flex-start",
                borderRadius: "999px",
                fontWeight: 600,
                marginTop: 1,
              }}
            >
              #{nextID ?? "N/A"}
            </Chip>

            {/* Name row */}
            <div className="grid grid-cols-2 gap-3">
              <Field label={t("first-name")} name="firstName" {...fieldProps} />
              <Field label={t("last-name")} name="lastName" {...fieldProps} />
            </div>

            <Field
              label={t("email")}
              name="email"
              type="email"
              {...fieldProps}
            />
            <Field
              label={t("phone-number")}
              name="phoneNumber"
              type="tel"
              {...fieldProps}
            />

            {/* Tickets + Invoice toggle */}
            <div className="grid grid-cols-2 gap-3 items-end">
              <FormControl required>
                <FormLabel>{t("tickets")}</FormLabel>
                <Input
                  name="tickets"
                  type="number"
                  value={formData.tickets}
                  onChange={handleChange}
                  slotProps={{ input: { min: 1 } }}
                  variant="soft"
                  sx={{ borderRadius: "10px" }}
                />
              </FormControl>
              <div className="flex items-center pb-2">
                <Checkbox
                  checked={invoice}
                  onChange={(e) => setInvoice(e.target.checked)}
                  label={t("invoice")}
                  variant="outlined"
                />
              </div>
            </div>

            {/* Invoice details (conditional) */}
            {invoice && (
              <div className="flex flex-col gap-3 pt-4 border-t border-blue-200">
                <Typography level="title-sm" color="primary">
                  {t("invoice-details")}
                </Typography>
                <Field
                  label={t("company-name")}
                  name="companyName"
                  {...fieldProps}
                />
                <div className="grid grid-cols-2 gap-3">
                  <Field
                    label={t("first-name")}
                    name="cmpFirstName"
                    {...fieldProps}
                  />
                  <Field
                    label={t("last-name")}
                    name="cpmLastName"
                    {...fieldProps}
                  />
                </div>
                <Field label={t("street")} name="street" {...fieldProps} />
                <Field
                  label={t("postal-code")}
                  name="postalCode"
                  {...fieldProps}
                />
                <Field
                  label={t("phone-number")}
                  name="cpmPhoneNumber"
                  type="tel"
                  {...fieldProps}
                />
                <Field
                  label={t("email")}
                  name="cpmEmail"
                  type="email"
                  {...fieldProps}
                />
              </div>
            )}

            {/* Payment method selection */}
            <FormControl required>
              <FormLabel>{t("select-payment-method")}</FormLabel>
              <div className="flex gap-2 flex-wrap mt-1">
                {PAYMENT_METHODS.map((method) => (
                  <Button
                    key={method}
                    variant={
                      formData.paymentMethod === method ? "solid" : "soft"
                    }
                    color="primary"
                    onClick={() => {
                      setFormData((prev) => ({
                        ...prev,
                        paymentMethod: method,
                      }));
                      if (method === "paypal") {
                        setQRmodal(true);
                      }
                    }}
                    sx={{
                      flex: 1,
                      minWidth: "90px",
                      borderRadius: "12px",
                      py: 1.5,
                      textTransform: "none",
                      fontWeight: formData.paymentMethod === method ? 700 : 400,
                    }}
                  >
                    {PAYMENT_LABELS[method]}
                  </Button>
                ))}
              </div>
              {/* Hidden required input to enforce payment selection on submit */}
              {!formData.paymentMethod && (
                <input
                  tabIndex={-1}
                  required
                  value=""
                  onChange={() => {}}
                  style={{
                    opacity: 0,
                    width: 0,
                    height: 0,
                    position: "absolute",
                  }}
                />
              )}
            </FormControl>

            {mutateFormIsPending ? (
              <div className="flex items-center justify-center">
                <CircularProgress />
              </div>
            ) : (
              <Button
                type="submit"
                disabled={!formData.paymentMethod}
                size="lg"
                sx={{
                  mt: 2,
                  borderRadius: "14px",
                  fontWeight: 700,
                  letterSpacing: "0.05em",
                  background: "linear-gradient(135deg, #2563eb, #1d4ed8)",
                  "&:hover": {
                    background: "linear-gradient(135deg, #1d4ed8, #1e40af)",
                  },
                }}
              >
                {t("submit")}
              </Button>
            )}

            {/* Message */}
            {msg && (
              <Alert
                color={msg.type}
                sx={{ flexDirection: "column", alignItems: "flex-start" }}
              >
                <Typography level="title-lg" sx={{ mb: 0.5 }}>
                  {msg.headline}
                </Typography>
                <Typography level="body-sm">{msg.text}</Typography>
              </Alert>
            )}
          </form>
        </Sheet>
      </div>
    </>
  );
};
