import {
  batch,
  Component,
  FlowComponent,
  For,
  Show,
  useContext,
  JSX,
  startTransition,
  createMemo,
  onMount,
  onCleanup,
} from "solid-js";
import { createStore, reconcile, unwrap } from "solid-js/store";
import { format, fromUnixTime, getUnixTime } from "date-fns";
import z from "myzod";
import Big from "big.js";
import { generate } from "node-iso11649";
import { customAlphabet } from "nanoid";

import createAccordion from "../Accordion";
import { Checkbox, TextArea, TextInput, UnixDateInput } from "../Form";
import { autoAnimate } from "~/directives/autoAnimate";
import {
  LocalStoreContext,
  localStoreSchema,
  POSITION_TYPE_AGILE,
  POSITION_TYPE_QUANTITY,
  PrintType,
  printTypeTitles,
  PRINT_TYPE_CONFIRMATION,
  PRINT_TYPE_INVOICE,
  PRINT_TYPE_OFFER,
  StoreContext,
  storeSchema,
  UiStoreContext,
} from "~/stores";
import { AddressData, isStructuredAddress } from "../Address";
import PositionsIcon from "~icons/carbon/show-data-cards";
import YouIcon from "~icons/carbon/face-wink";
import DesignIcon from "~icons/carbon/paint-brush";
import PrinterIcon from "~icons/carbon/printer";
import ProjectIcon from "~icons/carbon/product";
import DownloadIcon from "~icons/carbon/download";
import LoadIcon from "~icons/carbon/folder";
import LoadingSpinnerIcon from "~icons/icomoon-free/spinner9";
import ErrorIcon from "~icons/carbon/error";
import SuccessIcon from "~icons/carbon/checkmark-filled";
import CustomerIcon from "~icons/carbon/friendship";
import WarningIcon from "~icons/carbon/warning-alt-filled";
import GenerateIcon from "~icons/carbon/chemistry";

import { saveFile, selectLocalFiles, uploadFile } from "~/client/filesystem";
import { resetInput, sleep } from "~/util";
import { PositionsSettings } from "./Positions";
import Modal, { ModalCloseButton } from "../Modal";
import { createValidation } from "~/hooks/validation";
import { MarkdownHelpLabel } from "../Markdown";

const AccordionItemGrid: FlowComponent = (props) => {
  return (
    <div class="grid grid-cols-2 gap-3 gap-x-1 pb-3">{props.children}</div>
  );
};

const AccordionItemEnd: Component = () => {
  return <div class="h-1" />;
};

const AccordionItemDivider: FlowComponent = (props) => {
  return <div class="divider">{props.children}</div>;
};

const SettingsOverlay: Component = () => {
  const [state, setState] = useContext(StoreContext)!;
  const [localState, setLocalState] = useContext(LocalStoreContext)!;
  const [loadModal, setLoadModal] = createStore({
    open: false,
    loading: false,
    errors: null as null | {
      message?: JSX.Element;
      parseErrors: { path: string; message: string }[];
    },
  });
  const [uiState, setUiState] = useContext(UiStoreContext)!;

  const [AccordionItem] = createAccordion(null);

  autoAnimate;

  const [DocumentValidationContext, documentDataForm] = createValidation();
  const [YourDataValidationContext, yourDataForm] = createValidation();
  const [CustomerValidationContext, customerDataForm] = createValidation();

  const AddressInputs: Component<{
    namePrefix?: string;
    nameRequired?: boolean;
    setter: (name: string, value: any) => void;
    address: () => AddressData;
  }> = (props) => {
    const isStructured = createMemo(() => isStructuredAddress(props.address()));
    const withPrefix = (name: string) =>
      createMemo(
        () => `${props.namePrefix && props.namePrefix + "_"}${name}`
      )();

    return (
      <>
        <div class="col-span-2">
          <TextInput
            name={withPrefix("name")}
            label="Name"
            maxLength={70}
            required={props.nameRequired}
            value={props.address().name}
            onInput={(evt) => props.setter("name", evt.currentTarget.value)}
          />
        </div>
        <Show when={props.nameRequired || props.address().name}>
          <TextInput
            name={withPrefix("line1")}
            label={isStructured() ? "Strasse" : "Linie 1"}
            maxLength={70}
            required
            value={props.address().line1}
            onInput={(evt) => props.setter("line1", evt.currentTarget.value)}
          />
          <TextInput
            name={withPrefix("line2")}
            type={isStructured() ? "number" : "text"}
            label={isStructured() ? "Nummer" : "Linie 2"}
            maxLength={isStructured() ? undefined : 70}
            max={isStructured() ? 9999999999999999 : undefined}
            min={isStructured() ? 0 : undefined}
            required
            value={props.address().line2}
            onInput={(evt) => props.setter("line2", evt.currentTarget.value)}
          />
          <TextInput
            name={withPrefix("zip")}
            label="Plz"
            type="number"
            maxLength={16}
            min="0"
            value={props.address().zip}
            onInput={(evt) =>
              props.setter(
                "zip",
                parseInt(evt.currentTarget.value) || undefined
              )
            }
          />
          <TextInput
            name={withPrefix("city")}
            label="Ort"
            value={props.address().city}
            onInput={(evt) => props.setter("city", evt.currentTarget.value)}
          />
        </Show>
      </>
    );
  };

  const createCustomerAddressSetter = (alternative = false) => {
    const addressField = alternative ? "alternativeAddress" : "debtorAddress";

    return (name: any, value: any) => {
      setState("customer", addressField, name, value);
    };
  };

  const contactSetter = (name: any, value: any) => {
    setLocalState("contact", name, value);
  };

  const fullWidthLabelWidth = "50%";
  const FullWidthAccordionInput: Component<Parameters<typeof TextInput>[0]> = (
    props
  ) => (
    <div class="col-span-2">
      <TextInput labelMinWidth={fullWidthLabelWidth} {...props} />
    </div>
  );

  const saveProject = () => {
    const fileContent = JSON.stringify(
      {
        state: unwrap(state),
        localState: unwrap(localState),
      },
      null,
      "  "
    );

    saveFile(
      `rappli-${
        state.project.projectNumber.length
          ? state.project.projectNumber.replaceAll(" ", "-") + "-"
          : ""
      }${format(fromUnixTime(state.project.date), "yyyy-MM-dd")}.json`,
      "application/json",
      fileContent
    );

    setUiState("lastSaved", getUnixTime(new Date()));
  };

  const saveOnCtrlS = (e: KeyboardEvent) => {
    if (e.ctrlKey && e.key === "s") {
      e.preventDefault();
      saveProject();
    }
  };

  onMount(function () {
    document.addEventListener("keydown", saveOnCtrlS);
  });

  onCleanup(function () {
    document.removeEventListener("keydown", saveOnCtrlS);
  });

  return (
    <>
      <div class="print:hidden hidden xl:grid bg-white z-50 h-full fixed xxl:h-auto xxl:relative left-0 w-[480px] grid-rows-[1fr_auto] gap-4 p-3 transition-all shadow-none hover:shadow-2xl focus-within:shadow-2xl -translate-x-72 opacity-70 hover:opacity-100 focus-within:opacity-100 xxl:opacity-100 xxl:-translate-x-0 hover:translate-x-0 focus-within:translate-x-0 ">
        <div class="overflow-y-scroll">
          <AccordionItem
            item={0}
            activeTitleColor="text-violet-600"
            label={
              <>
                <ProjectIcon />
                Dokument
                <Show when={!documentDataForm.valid}>
                  <WarningIcon class="text-error" />
                </Show>
              </>
            }
          >
            {/* TODO: Add option for item price decimals */}
            <DocumentValidationContext>
              <AccordionItemGrid>
                <FullWidthAccordionInput
                  label="Projekt Nr."
                  value={state.project.projectNumber}
                  onInput={(evt) =>
                    setState(
                      "project",
                      "projectNumber",
                      evt.currentTarget.value
                    )
                  }
                />
                <FullWidthAccordionInput
                  label="Bestellungs Nr."
                  value={state.project.orderNumber}
                  onInput={(evt) =>
                    setState("project", "orderNumber", evt.currentTarget.value)
                  }
                />
                <div class="col-span-2">
                  <UnixDateInput
                    required
                    labelMinWidth={fullWidthLabelWidth}
                    label="Datum"
                    value={state.project.date}
                    onInput={(v: any) => setState("project", "date", v)}
                  />
                </div>
                <FullWidthAccordionInput
                  label="Lieferungs Nr."
                  value={state.project.deliveryNumber}
                  onInput={(evt) =>
                    setState(
                      "project",
                      "deliveryNumber",
                      evt.currentTarget.value
                    )
                  }
                />

                <div class="col-span-2">
                  <UnixDateInput
                    labelMinWidth={fullWidthLabelWidth}
                    label="Lieferdatum"
                    value={state.project.deliveryDate}
                    onInput={(v: any) => setState("project", "deliveryDate", v)}
                  />
                </div>
                <div class="col-span-2">
                  <div class="input-group input-group-sm">
                    <span style={{ "min-width": fullWidthLabelWidth }}>
                      Typ neuer Positionen
                    </span>
                    <select
                      title="Neue Positionen werden mit diesem Typen erzeugt."
                      class="flex-1 select select-sm select-bordered"
                      onChange={(e) =>
                        setState(
                          "defaultPositionType",
                          e.currentTarget.value as any
                        )
                      }
                    >
                      <For
                        each={[
                          [POSITION_TYPE_QUANTITY, "Menge"],
                          [POSITION_TYPE_AGILE, "Agile"],
                        ]}
                      >
                        {([type, label]) => (
                          <option
                            selected={type === state.defaultPositionType}
                            value={type}
                          >
                            {label}
                          </option>
                        )}
                      </For>
                    </select>
                  </div>
                </div>

                <FullWidthAccordionInput
                  required
                  type="number"
                  label="Standard Einzelpreis"
                  value={state.defaultItemPrice}
                  onInput={(evt) =>
                    setState(
                      "defaultItemPrice",
                      parseFloat(evt.currentTarget.value) || 0
                    )
                  }
                />

                <div class="col-span-2">
                  <TextArea
                    label="Einleitung"
                    labelSuffixJsx={<MarkdownHelpLabel />}
                    value={state.project.preface}
                    onInput={(evt) => {
                      setState("project", "preface", evt.currentTarget.value);
                    }}
                  />
                </div>

                <div class="col-span-2">
                  <TextArea
                    label="Schlussbemerkung"
                    labelSuffixJsx={<MarkdownHelpLabel />}
                    value={state.project.conclusion}
                    onInput={(evt) =>
                      setState("project", "conclusion", evt.currentTarget.value)
                    }
                  />
                </div>
              </AccordionItemGrid>
              <AccordionItemEnd />
              <AccordionItemDivider>QR Rechnung</AccordionItemDivider>
              <AccordionItemGrid>
                <FullWidthAccordionInput
                  vertical={true}
                  label="Referenz"
                  value={state.invoice.reference}
                  onInput={(evt) =>
                    setState("invoice", "reference", evt.currentTarget.value)
                  }
                />

                <div class="col-span-2">
                  <button
                    class="btn btn-xs btn-block btn-accent gap-2"
                    onClick={() => {
                      let value = state.invoice.reference;
                      if (value.startsWith("RF")) {
                        return;
                      }

                      if (value === "") {
                        value = customAlphabet("1234567890", 21)() + "";
                      }

                      setState("invoice", "reference", generate(value));
                    }}
                  >
                    <GenerateIcon /> Kreditor Referenz generieren
                  </button>
                </div>
                <div class="col-span-2">
                  <TextInput
                    vertical={true}
                    maxLength={140}
                    label="Zusätzliche Informationen"
                    value={state.invoice.message}
                    onInput={(evt) =>
                      setState("invoice", "message", evt.currentTarget.value)
                    }
                  />
                </div>
              </AccordionItemGrid>
              <AccordionItemEnd />
              <AccordionItemDivider>Agile</AccordionItemDivider>
              <AccordionItemGrid>
                <div class="col-span-2">
                  <TextInput
                    required
                    title={
                      'Agile Positionen werden mit Story Points "geschätzt". Was ist der kleinst mögliche Aufwand einer einzelnen Agilen Position?'
                    }
                    type="number"
                    label="Stunden pro Story Point"
                    onInput={(evt) =>
                      evt.currentTarget.value !== "" &&
                      setState(
                        "agileHoursPerStoryPoint",
                        parseFloat(evt.currentTarget.value)
                      )
                    }
                    onBlur={resetInput(0)}
                    value={state.agileHoursPerStoryPoint}
                  />
                </div>
                <div class="col-span-2">
                  <div class="form-control">
                    <label class="label gap-8">
                      <span class="label-text font-bold">Risiko Faktor</span>
                      <div class="flex-1">
                        <input
                          class="range range-xs hover:range-accent"
                          required
                          type="range"
                          title="Wie hoch ist das Risiko, dass etwas schief geht? Dieser Wert dient zur Gewichtung des Mittelwerts zwischen den minimalen und maximalen Story Points pro Position. Bei einem Risiko von 0% werden nur die minimalen Story Points der Positionen berücksichtigt, bei einem Risiko von 100% nur die Maximalen. (0 - 100%)"
                          value={state.agileRiskFactor}
                          min="0.0"
                          max="1.0"
                          step="0.1"
                          onInput={(evt) =>
                            evt.currentTarget.value !== "" &&
                            setState(
                              "agileRiskFactor",
                              parseFloat(evt.currentTarget.value)
                            )
                          }
                          onBlur={resetInput(0)}
                        />
                        <div class="w-full flex justify-between text-xs px-2 relative">
                          <span>
                            <div class="absolute left-0">Klein</div>&nbsp;
                          </span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>|</span>
                          <span>
                            <div class="absolute text-right right-0">Gross</div>
                            &nbsp;
                          </span>
                        </div>
                      </div>
                    </label>
                  </div>
                </div>
              </AccordionItemGrid>
            </DocumentValidationContext>
          </AccordionItem>
          <AccordionItem
            item={1}
            activeTitleColor="text-cyan-500"
            label={
              <>
                <YouIcon />
                Deine Angaben
                <Show when={!yourDataForm.valid}>
                  <WarningIcon class="text-error" />
                </Show>
              </>
            }
          >
            <YourDataValidationContext>
              <AccordionItemDivider>Bank Verbindung</AccordionItemDivider>
              <AccordionItemGrid>
                <div class="col-span-2">
                  <TextInput
                    required
                    label="Iban"
                    value={localState.iban}
                    onInput={(evt) =>
                      setLocalState("iban", evt.currentTarget.value)
                    }
                  />
                </div>
                <AddressInputs
                  namePrefix="creditor"
                  nameRequired={true}
                  setter={(name, value) => {
                    setLocalState("creditor", name as any, value);
                  }}
                  address={() => localState.creditor}
                />
              </AccordionItemGrid>
              <AccordionItemEnd />
              <AccordionItemDivider>
                Abweichene Adresse{" "}
                <input
                  class="checkbox"
                  type="checkbox"
                  checked={localState.useCustomAddress}
                  onChange={(evt) =>
                    setLocalState("useCustomAddress", evt.currentTarget.checked)
                  }
                />
              </AccordionItemDivider>
              <div use:autoAnimate>
                <Show when={localState.useCustomAddress}>
                  <AccordionItemGrid>
                    <AddressInputs
                      namePrefix="customAddress"
                      nameRequired={true}
                      setter={(name, value) => {
                        setLocalState("customAddress", name as any, value);
                      }}
                      address={() => localState.customAddress}
                    />
                  </AccordionItemGrid>
                </Show>
              </div>
              <AccordionItemEnd />

              <AccordionItemDivider>Ansprechpartner</AccordionItemDivider>
              <AccordionItemGrid>
                <div class="col-span-2">
                  <TextInput
                    label="Name"
                    value={localState.contact?.name}
                    onInput={(evt) =>
                      contactSetter("name", evt.currentTarget.value)
                    }
                  />
                </div>

                <TextInput
                  label="Telefon"
                  value={localState.contact?.phone}
                  onInput={(evt) =>
                    contactSetter("phone", evt.currentTarget.value)
                  }
                />
                <TextInput
                  label="E-Mail"
                  value={localState.contact?.email}
                  type="email"
                  onInput={(evt) =>
                    contactSetter("email", evt.currentTarget.value)
                  }
                />
              </AccordionItemGrid>
              <AccordionItemEnd />

              <AccordionItemDivider>Andere Angaben</AccordionItemDivider>
              <AccordionItemGrid>
                <FullWidthAccordionInput
                  vertical={true}
                  label="Zahlungsbedingungen"
                  value={localState.paymentTerms}
                  onInput={(evt) =>
                    setLocalState("paymentTerms", evt.currentTarget.value)
                  }
                />
                <div class="col-span-2">
                  <TextInput
                    label="MwST-Nr."
                    value={localState.vatNumber}
                    onInput={(evt) =>
                      setLocalState("vatNumber", evt.currentTarget.value)
                    }
                  />
                </div>
                <div class="col-span-2">
                  <TextInput
                    required
                    label="MwST-Satz"
                    type="number"
                    step="0.1"
                    suffix="%"
                    value={new Big(localState.vatRate).mul(100).toNumber()}
                    onInput={(evt) => {
                      evt.currentTarget.value !== "" &&
                        setLocalState(
                          "vatRate",
                          new Big(evt.currentTarget.value).div(100).toNumber()
                        );
                    }}
                    onBlur={resetInput(0)}
                  />
                </div>
              </AccordionItemGrid>
              <AccordionItemEnd />

              <AccordionItemDivider>Corporate Design</AccordionItemDivider>
              <AccordionItemGrid>
                <div class="col-span-2">
                  <TextInput
                    label="Logo"
                    type="file"
                    class="file-input"
                    accept="image/png, image/jpeg, image/svg+xml"
                    onInput={async (evt) => {
                      if (!evt.currentTarget.files) {
                        return;
                      }

                      const file = evt.currentTarget.files[0];
                      if (!file) {
                        return;
                      }

                      const content = await uploadFile(file, "dataUrl");
                      if (!content) {
                        return;
                      }

                      const image = document.createElement("img");
                      image.src = content;
                      image.onload = function () {
                        setLocalState("logo", {
                          width: image.width,
                          height: image.height,
                          type: file.type,
                          url: content,
                        });
                      };
                    }}
                  />
                </div>
              </AccordionItemGrid>
            </YourDataValidationContext>
          </AccordionItem>
          <AccordionItem
            item={2}
            activeTitleColor="text-emerald-500"
            label={
              <>
                <CustomerIcon /> Kunde
                <Show when={!customerDataForm.valid}>
                  <WarningIcon class="text-error" />
                </Show>
              </>
            }
          >
            <CustomerValidationContext>
              <AccordionItemDivider>Bank Verbindung</AccordionItemDivider>
              <AccordionItemGrid>
                <AddressInputs
                  namePrefix="debtor"
                  setter={createCustomerAddressSetter()}
                  address={() => state.customer.debtorAddress}
                />
              </AccordionItemGrid>
              <AccordionItemEnd />
              <AccordionItemDivider>
                Abweichende Adresse{" "}
                <input
                  class="checkbox"
                  type="checkbox"
                  checked={state.useCustomerAlternativeAddress}
                  onChange={(evt) =>
                    setState(
                      "useCustomerAlternativeAddress",
                      evt.currentTarget.checked
                    )
                  }
                />
              </AccordionItemDivider>
              <div use:autoAnimate>
                <Show when={state.useCustomerAlternativeAddress}>
                  <AccordionItemGrid>
                    <AddressInputs
                      setter={createCustomerAddressSetter(true)}
                      address={() => state.customer.alternativeAddress}
                    />
                  </AccordionItemGrid>
                </Show>
              </div>
              <AccordionItemEnd />
              <AccordionItemDivider>Andere Angaben</AccordionItemDivider>
              <AccordionItemGrid>
                <FullWidthAccordionInput
                  label="Kunden Nr."
                  value={state.customer.customerNumber}
                  onInput={(evt) =>
                    setState(
                      "customer",
                      "customerNumber",
                      evt.currentTarget.value
                    )
                  }
                />

                <FullWidthAccordionInput
                  label="MwST-Nr."
                  value={state.customer.vatNumber}
                  onInput={(evt) =>
                    setState("customer", "vatNumber", evt.currentTarget.value)
                  }
                />
              </AccordionItemGrid>
            </CustomerValidationContext>
          </AccordionItem>
          <AccordionItem
            item={3}
            activeTitleColor="text-orange-400"
            label={
              <>
                <PositionsIcon />
                Positionen
                <small>({state.positions.length})</small>
              </>
            }
          >
            <PositionsSettings />
          </AccordionItem>
          <AccordionItem
            activeTitleColor="text-blue-500"
            label={
              <>
                <DesignIcon />
                Design
              </>
            }
            item={4}
          >
            <AccordionItemGrid>
              <div class="col-span-2">
                <Checkbox
                  checked={localState.showLufraiWatermark}
                  onChange={(evt) =>
                    setLocalState(
                      "showLufraiWatermark",
                      evt.currentTarget.checked
                    )
                  }
                >
                  Lufrai Wasserzeichen anzeigen
                </Checkbox>
              </div>
              <div class="col-span-2">
                <Checkbox
                  checked={state.fullWidthInvoice}
                  onChange={(evt) =>
                    setState("fullWidthInvoice", evt.currentTarget.checked)
                  }
                >
                  Abstandlose QR Rechnung
                </Checkbox>
              </div>
            </AccordionItemGrid>
          </AccordionItem>
        </div>
        <div>
          <div class="grid grid-cols-2 gap-2 mb-4">
            <button
              class="btn btn-sm btn-accent shadow-md gap-2"
              onClick={async () => {
                const files = await selectLocalFiles([
                  ".json",
                  "application/json",
                ]);
                if (!files[0]) {
                  return;
                }

                setLoadModal("loading", true);
                setLoadModal("errors", null);
                await sleep(200);
                setLoadModal("open", true);

                const load = async () => {
                  const results = await Promise.all([
                    uploadFile(files[0]),
                    sleep(600),
                  ]);

                  const content = results[0];

                  if (!content) {
                    setLoadModal("errors", {
                      message:
                        "Das Dokument ist leer! Bitte lade ein korrektes Dokument hoch.",
                    });
                    return;
                  }

                  let contentObject: any;

                  try {
                    contentObject = JSON.parse(content);
                  } catch (err) {
                    setLoadModal("errors", {
                      message: "Das Dokument hat kein gültiges Format.",
                    });
                    return;
                  }

                  // TODO: Run migrations

                  const schema = z
                    .object({
                      state: storeSchema,
                      localState: localStoreSchema,
                    })
                    .collectErrors();

                  try {
                    schema.parse(contentObject);
                  } catch (e: any) {
                    const message = "Das Dokument hat kein gültiges Format.";

                    let parseErrors = [{ path: ".", message: e.message }];
                    if (e.collectedErrors) {
                      parseErrors = Object.values(e.collectedErrors).map(
                        (error: any) => {
                          return {
                            path: error.path.join("."),
                            message: error.message,
                          };
                        }
                      );
                    }

                    setLoadModal("errors", {
                      message,
                      parseErrors,
                    });

                    return;
                  }

                  await startTransition(function () {
                    batch(() => {
                      setState(reconcile(contentObject.state));
                      setLocalState(reconcile(contentObject.localState));
                    });
                  });
                };

                const results = await Promise.all([sleep(1200), load()]);

                setLoadModal("loading", false);

                if (!loadModal.errors) {
                  await sleep(1100);
                  setLoadModal("open", false);
                }
              }}
            >
              <LoadIcon /> Laden
            </button>
            <button
              class="btn btn-sm btn-accent shadow-md gap-2"
              onClick={saveProject}
            >
              <DownloadIcon /> Speichern
            </button>
          </div>
          <div class="form-control w-full">
            <div class="input-group input-group-sm">
              <select
                class="w-1/2 select select-sm select-bordered shadow"
                onChange={(evt) => {
                  setUiState("printType", evt.currentTarget.value as any);
                  evt.currentTarget.blur();
                }}
              >
                <For
                  each={
                    [
                      PRINT_TYPE_OFFER,
                      PRINT_TYPE_CONFIRMATION,
                      PRINT_TYPE_INVOICE,
                    ] as PrintType[]
                  }
                >
                  {(type) => (
                    <option value={type} selected={type === uiState.printType}>
                      {printTypeTitles[type]}
                    </option>
                  )}
                </For>
              </select>
              <button
                class="btn btn-sm btn-primary flex-1 gap-2 shadow-md"
                onClick={() => window.print()}
              >
                <PrinterIcon /> Drucken
              </button>
            </div>
          </div>
        </div>
      </div>
      <Show when={true}>
        <Modal open={loadModal.open}>
          <Show when={!loadModal.loading && loadModal.errors}>
            <ModalCloseButton
              onClick={() => {
                setLoadModal("open", false);
              }}
            />
          </Show>
          <div use:autoAnimate class="flex flex-col items-center">
            <Show when={!loadModal.loading}>
              <Show when={loadModal.errors}>
                <div class="flex items-center gap-2 text-xl text-error mb-10">
                  <ErrorIcon />
                  <div class="font-black">
                    Dokument konnte nicht geladen werden
                  </div>
                </div>
                <Show when={loadModal.errors?.message}>
                  <div class="text-5xl font-light text-error-content text-center">
                    {loadModal.errors?.message}
                  </div>
                </Show>

                <Show when={loadModal.errors?.parseErrors}>
                  <table class="mt-6 w-full table table-compact">
                    <thead>
                      <tr>
                        <th></th>
                        <th>JSON-Pfad</th>
                        <th>Fehler</th>
                      </tr>
                    </thead>
                    <tbody>
                      <For each={loadModal.errors?.parseErrors}>
                        {(error, idx) => (
                          <tr>
                            <th>{idx() + 1}</th>
                            <td class="break-words">{error.path}</td>
                            <td>{error.message}</td>
                          </tr>
                        )}
                      </For>
                    </tbody>
                  </table>
                </Show>

                <button
                  class="mt-8 btn"
                  onClick={() => {
                    setLoadModal("open", false);
                    setLoadModal("errors", null);
                  }}
                >
                  Schliessen
                </button>
              </Show>
              <Show when={!loadModal.errors}>
                <div class="flex justify-center">
                  <div class="animate-pulse text-7xl text-success">
                    <SuccessIcon />
                  </div>
                </div>
              </Show>
            </Show>

            <Show when={loadModal.loading}>
              <div class="flex justify-center">
                <div class="animate-spin text-7xl text-primary">
                  <LoadingSpinnerIcon />
                </div>
              </div>
            </Show>
          </div>
        </Modal>
      </Show>
    </>
  );
};

export default SettingsOverlay;
