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,
  NumberInput,
  Select,
  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="text"
            label={isStructured() ? "Nummer" : "Linie 2"}
            maxLength={isStructured() ? 16 : 70}
            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);
  });

  const AccordionItemLabel: FlowComponent = (props) => (
    <span class="overflow-hidden whitespace-nowrap hidden xxl:inline-flex group-hover:inline-flex group-focus-within:inline-flex gap-2">
      {props.children}
    </span>
  );

  const AccordionContent: FlowComponent = (props) => (
    <div class="min-w-[300px]">{props.children}</div>
  );

  return (
    <>
      <div class="group print:hidden hidden lg:grid bg-white z-50 h-full fixed xxl:h-auto xxl:relative left-0 xxl:w-[480px] grid-rows-[1fr_auto] gap-4 p-1 xxl:p-3 transition-all shadow hover:shadow-2xl focus-within:shadow-2xl outline outline-1 outline-slate-700/10 w-24 hover:w-[480px] focus-within:w-[480px]">
        <div class="overflow-y-scroll">
          <AccordionItem
            item={0}
            activeTitleColor="text-violet-600"
            label={
              <>
                <ProjectIcon />
                <AccordionItemLabel>Dokument</AccordionItemLabel>
                <Show when={!documentDataForm.valid}>
                  <AccordionItemLabel>
                    <WarningIcon class="text-error" />
                  </AccordionItemLabel>
                </Show>
              </>
            }
          >
            {/* TODO: Add option for item price decimals */}
            <AccordionContent>
              <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">
                    <Select
                      label="Typ neuer Positionen"
                      labelMinWidth={fullWidthLabelWidth}
                      title="Neue Positionen werden mit diesem Typ erzeugt."
                      value={state.defaultPositionType}
                      options={[
                        [POSITION_TYPE_QUANTITY, "Menge"],
                        [POSITION_TYPE_AGILE, "Agile"],
                      ]}
                      onChange={(v) =>
                        setState("defaultPositionType", v as any)
                      }
                    />
                  </div>

                  <div class="col-span-2">
                    <NumberInput
                      required
                      label="Standard Einzelpreis"
                      labelMinWidth={fullWidthLabelWidth}
                      value={state.defaultItemPrice}
                      onInput={(v) =>
                        v != null && setState("defaultItemPrice", v)
                      }
                      onBlur={resetInput(0)}
                    />
                  </div>

                  <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>
            </AccordionContent>
          </AccordionItem>
          <AccordionItem
            item={1}
            activeTitleColor="text-cyan-500"
            label={
              <>
                <YouIcon />
                <AccordionItemLabel>Deine Angaben</AccordionItemLabel>
                <Show when={!yourDataForm.valid}>
                  <AccordionItemLabel>
                    <WarningIcon class="text-error" />
                  </AccordionItemLabel>
                </Show>
              </>
            }
          >
            <AccordionContent>
              <YourDataValidationContext>
                <AccordionItemDivider>Bank Verbindung</AccordionItemDivider>
                <AccordionItemGrid>
                  <div class="col-span-2">
                    <TextInput
                      required
                      label="Iban"
                      maxLength={50}
                      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>
                  Abweichende 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">
                    <NumberInput
                      required
                      label="MwST-Satz"
                      suffix="%"
                      value={new Big(localState.vatRate).mul(100).toNumber()}
                      onInput={(v) => {
                        v != null &&
                          setLocalState(
                            "vatRate",
                            new Big(v).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>
            </AccordionContent>
          </AccordionItem>
          <AccordionItem
            item={2}
            activeTitleColor="text-emerald-500"
            label={
              <>
                <CustomerIcon />
                <AccordionItemLabel>Kunde</AccordionItemLabel>
                <Show when={!customerDataForm.valid}>
                  <AccordionItemLabel>
                    <WarningIcon class="text-error" />
                  </AccordionItemLabel>
                </Show>
              </>
            }
          >
            <AccordionContent>
              <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>
            </AccordionContent>
          </AccordionItem>
          <AccordionItem
            item={3}
            activeTitleColor="text-orange-400"
            label={
              <>
                <PositionsIcon />
                <AccordionItemLabel>
                  Positionen <small>({state.positions.length})</small>
                </AccordionItemLabel>
              </>
            }
          >
            <AccordionContent>
              <PositionsSettings />
            </AccordionContent>
          </AccordionItem>
          <AccordionItem
            activeTitleColor="text-blue-500"
            label={
              <>
                <DesignIcon />
                <AccordionItemLabel>Design</AccordionItemLabel>
              </>
            }
            item={4}
          >
            <AccordionContent>
              <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>
            </AccordionContent>
          </AccordionItem>
        </div>
        <div class="overflow-hidden transition-opacity opacity-90 group-hover:opacity-100 group-focus-within:opacity-100 xxl:opacity-100">
          <AccordionContent>
            <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>
          </AccordionContent>
        </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>{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;
