import { useTranslation } from "react-i18next";
import { useState, useEffect } 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";
import { useForm } from "@tanstack/react-form";
import { changeTranslation } from "../utils/uxFncs";
import { createFormSchema } from "../config/interfaces.config";
import type { ZodObject, ZodRawShape } from "zod";
import { TextField } from "../components/TextField";

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

/**
 * Validates a single field against the full Zod schema.
 * Returns the first error message for that field, or undefined if valid.
 */
function validateFieldWithZod(
  schema: ZodObject<ZodRawShape>,
  fieldName: string,
  allValues: Record<string, unknown>,
): string | undefined {
  const result = schema.safeParse(allValues);
  if (result.success) return undefined;
  const issue = result.error.issues.find(
    (i) => i.path.length === 1 && i.path[0] === fieldName,
  );
  return issue?.message;
}

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

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

  const formSchema = createFormSchema(t, invoice);

  const makeFieldValidator = (fieldName: string) => ({
    onSubmit: ({
      fieldApi,
    }: {
      fieldApi: { form: { state: { values: Record<string, unknown> } } };
    }) => {
      const allValues = fieldApi.form.state.values;
      return validateFieldWithZod(formSchema, fieldName, allValues);
    },
    onBlur: ({
      fieldApi,
    }: {
      fieldApi: { form: { state: { values: Record<string, unknown> } } };
    }) => {
      const allValues = fieldApi.form.state.values;
      return validateFieldWithZod(formSchema, fieldName, allValues);
    },
  });

  const { Field, Subscribe, handleSubmit, setFieldValue } = useForm({
    defaultValues: {
      firstName: "",
      lastName: "",
      email: "",
      phoneNumber: "",
      tickets: 1,
      companyName: "",
      cmpFirstName: "",
      cpmLastName: "",
      cpmEmail: "",
      cpmPhoneNumber: "",
      street: "",
      postalCode: "",
      paymentMethod: "",
    },
    onSubmit: async ({ value }) => {
      const result = formSchema.safeParse(value);
      if (!result.success) return;
      mutateForm(value as FormData);
    },
  });

  const getErrors = (field: {
    state: { meta: { errorMap: Record<string, unknown> } };
  }) => {
    const normalizeErrors = (value: unknown) => {
      if (Array.isArray(value)) return value as string[];
      if (typeof value === "string" && value.length > 0) return [value];
      return [] as string[];
    };

    const blurErrors = normalizeErrors(field.state.meta.errorMap["onBlur"]);
    const submitErrors = normalizeErrors(field.state.meta.errorMap["onSubmit"]);
    return [...blurErrors, ...submitErrors].filter(Boolean);
  };

  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: (values: FormData) => submitFormData(values, selectedUser),
    onSuccess: (_, values) => {
      queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
      document.location.href = `/success?id=${nextID}&tickets=${values.tickets}`;
    },
    onError: () => {
      queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
      setMsg({
        type: "danger",
        headline: t("error"),
        text: t("form-submission-failed"),
      });
    },
  });

  const nextID = userData?.nextID ?? "N/A";

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

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

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

      <div className="flex-1 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>
            <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();
              handleSubmit();
            }}
            className="flex flex-col gap-4"
          >
            <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
                name="firstName"
                validators={makeFieldValidator("firstName")}
              >
                {(field) => (
                  <TextField
                    label={t("first-name")}
                    required
                    value={field.state.value}
                    onBlur={field.handleBlur}
                    onChange={field.handleChange}
                    errors={getErrors(field)}
                  />
                )}
              </Field>

              <Field
                name="lastName"
                validators={makeFieldValidator("lastName")}
              >
                {(field) => (
                  <TextField
                    label={t("last-name")}
                    required
                    value={field.state.value}
                    onBlur={field.handleBlur}
                    onChange={field.handleChange}
                    errors={getErrors(field)}
                  />
                )}
              </Field>
            </div>

            <Field name="email" validators={makeFieldValidator("email")}>
              {(field) => (
                <TextField
                  label={t("email")}
                  type="email"
                  required
                  value={field.state.value}
                  onBlur={field.handleBlur}
                  onChange={field.handleChange}
                  errors={getErrors(field)}
                />
              )}
            </Field>

            <Field
              name="phoneNumber"
              validators={makeFieldValidator("phoneNumber")}
            >
              {(field) => (
                <TextField
                  label={t("phone-number")}
                  type="tel"
                  required
                  value={field.state.value}
                  onBlur={field.handleBlur}
                  onChange={field.handleChange}
                  errors={getErrors(field)}
                />
              )}
            </Field>

            {/* Tickets + Invoice toggle */}
            <div className="grid grid-cols-2 gap-3 items-end">
              <FormControl required>
                <FormLabel>{t("tickets")}</FormLabel>
                <Field
                  name="tickets"
                  validators={makeFieldValidator("tickets")}
                >
                  {(field) => {
                    const errors = getErrors(field);
                    return (
                      <>
                        <Input
                          type="number"
                          value={field.state.value ?? ""}
                          onBlur={field.handleBlur}
                          onChange={(e) =>
                            field.handleChange(Number(e.target.value))
                          }
                          slotProps={{ input: { min: 1 } }}
                          variant="soft"
                          sx={{ borderRadius: "10px" }}
                        />
                        {errors.length > 0 && (
                          <span className="text-red-500 text-sm">
                            {errors[0]}
                          </span>
                        )}
                      </>
                    );
                  }}
                </Field>
              </FormControl>
              <div className="flex items-center pb-2">
                <Checkbox
                  checked={invoice}
                  onChange={(e) => {
                    const checked = e.target.checked;
                    setInvoice(checked);
                    if (!checked) {
                      setFieldValue("companyName", "");
                      setFieldValue("cmpFirstName", "");
                      setFieldValue("cpmLastName", "");
                      setFieldValue("cpmEmail", "");
                      setFieldValue("cpmPhoneNumber", "");
                      setFieldValue("street", "");
                      setFieldValue("postalCode", "");
                    }
                  }}
                  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
                  name="companyName"
                  validators={makeFieldValidator("companyName")}
                >
                  {(field) => (
                    <TextField
                      label={t("company-name")}
                      required
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={field.handleChange}
                      errors={getErrors(field)}
                    />
                  )}
                </Field>

                <div className="grid grid-cols-2 gap-3">
                  <Field
                    name="cmpFirstName"
                    validators={makeFieldValidator("cmpFirstName")}
                  >
                    {(field) => (
                      <TextField
                        label={t("first-name")}
                        required
                        value={field.state.value}
                        onBlur={field.handleBlur}
                        onChange={field.handleChange}
                        errors={getErrors(field)}
                      />
                    )}
                  </Field>

                  <Field
                    name="cpmLastName"
                    validators={makeFieldValidator("cpmLastName")}
                  >
                    {(field) => (
                      <TextField
                        label={t("last-name")}
                        required
                        value={field.state.value}
                        onBlur={field.handleBlur}
                        onChange={field.handleChange}
                        errors={getErrors(field)}
                      />
                    )}
                  </Field>
                </div>

                <Field name="street" validators={makeFieldValidator("street")}>
                  {(field) => (
                    <TextField
                      label={t("street")}
                      required
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={field.handleChange}
                      errors={getErrors(field)}
                    />
                  )}
                </Field>

                <Field
                  name="postalCode"
                  validators={makeFieldValidator("postalCode")}
                >
                  {(field) => (
                    <TextField
                      label={t("postal-code")}
                      required
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={field.handleChange}
                      errors={getErrors(field)}
                    />
                  )}
                </Field>

                <Field
                  name="cpmPhoneNumber"
                  validators={makeFieldValidator("cpmPhoneNumber")}
                >
                  {(field) => (
                    <TextField
                      label={t("phone-number")}
                      type="tel"
                      required
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={field.handleChange}
                      errors={getErrors(field)}
                    />
                  )}
                </Field>

                <Field
                  name="cpmEmail"
                  validators={makeFieldValidator("cpmEmail")}
                >
                  {(field) => (
                    <TextField
                      label={t("email")}
                      type="email"
                      required
                      value={field.state.value}
                      onBlur={field.handleBlur}
                      onChange={field.handleChange}
                      errors={getErrors(field)}
                    />
                  )}
                </Field>
              </div>
            )}

            {/* Payment method selection */}
            <FormControl required>
              <FormLabel>{t("select-payment-method")}</FormLabel>
              <Subscribe selector={(state) => state.values.paymentMethod}>
                {(paymentMethod) => (
                  <div className="flex gap-2 flex-wrap mt-1">
                    {PAYMENT_METHODS.map((method) => (
                      <Button
                        key={method}
                        variant={paymentMethod === method ? "solid" : "soft"}
                        color="primary"
                        onClick={() => {
                          setFieldValue("paymentMethod", method);
                          if (method === "paypal") {
                            setQRmodal(true);
                          }
                        }}
                        sx={{
                          flex: 1,
                          minWidth: "90px",
                          borderRadius: "12px",
                          py: 1.5,
                          textTransform: "none",
                          fontWeight: paymentMethod === method ? 700 : 400,
                        }}
                      >
                        {PAYMENT_LABELS[method]}
                      </Button>
                    ))}
                  </div>
                )}
              </Subscribe>
            </FormControl>

            {mutateFormIsPending ? (
              <div className="flex items-center justify-center">
                <CircularProgress />
              </div>
            ) : (
              <Subscribe selector={(state) => state.values.paymentMethod}>
                {(paymentMethod) => (
                  <Button
                    type="submit"
                    disabled={!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>
                )}
              </Subscribe>
            )}

            {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>
    </>
  );
};
