import AddIcon from "@mui/icons-material/Add";
import ClearIcon from "@mui/icons-material/Clear";
import { IconButton, Tooltip, Typography } from "@mui/material";
import React, { useRef } from "react";
import { Account } from "../api/AccountApi";
import { UploadedFile } from "../api/FileApi";
import { InboxApi } from "../api/InboxApi";
import { MovementApi } from "../api/MovementsApi";
import { ServerApi } from "../api/ServerApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { time } from "../utils/DateUtils";
import { firstLetterUppercase } from "../utils/StringUtils";
import { AmountInput } from "./forms/AmountInput";
import { DateInput } from "./forms/DateInput";
import { TextInput } from "./forms/TextInput";
import { UploadFileButton } from "./forms/UploadFileButton";
import { UploadedFileWidget } from "./UploadedFileWidget";

export function NewMovementWidget(
  p: {
    onCreated: () => void;
  } & ({ isInbox: true } | { isInbox?: undefined; account: Account })
): React.ReactElement {
  const snackbar = useSnackbar();
  const alert = useAlert();

  const dateInputRef = useRef<HTMLInputElement>(null);

  const [file, setFile] = React.useState<UploadedFile | undefined>();
  const [movTime, setMovTime] = React.useState<number | undefined>(time());
  const [label, setLabel] = React.useState<string | undefined>("");
  const [amount, setAmount] = React.useState<number | undefined>(0);

  const entity = p.isInbox ? "inbox entry" : "movement";

  const submit = async (e: React.SyntheticEvent<any>) => {
    e.preventDefault();

    if (!p.isInbox && (label?.length ?? 0) === 0) {
      alert(`Please specify ${entity} label!`);
      return;
    }

    if (p.isInbox && !file) {
      alert(`Please specify ${entity} file!`);
      return;
    }

    if (!movTime) {
      alert(`Please specify ${entity} date!`);
      return;
    }

    if (!amount && !p.isInbox) {
      alert(`Please specify ${entity} amount!`);
      return;
    }

    try {
      if (!p.isInbox) {
        await MovementApi.Create({
          account_id: p.account.id,
          checked: false,
          amount: amount!,
          label: label!,
          time: movTime,
        });
      } else {
        await InboxApi.Create({
          file_id: file!.id,
          amount: amount,
          label: label,
          time: movTime,
        });
      }

      snackbar(`The ${entity} was successfully created!`);

      p.onCreated();

      setFile(undefined);
      setLabel("");
      setAmount(0);

      // Give back focus to date input
      dateInputRef.current?.querySelector("input")?.focus();
    } catch (e) {
      console.error(`Failed to create ${entity}!`, e);
      alert(`Failed to create ${entity}! ${e}`);
    }
  };

  return (
    <form
      onSubmit={submit}
      style={{ marginTop: "10px", display: "flex", alignItems: "center" }}
    >
      {/* Label */}
      {/* Add label only when creating movement */}
      {!p.isInbox ? (
        <Typography style={{ marginRight: "10px" }}>New {entity}</Typography>
      ) : (
        <></>
      )}
      {/* File input */}
      {/* Add file only when creating inbox entries */}
      {p.isInbox ? (
        file ? (
          <>
            <span
              style={{
                flex: 1,
                maxWidth: "100px",
                overflow: "hidden",
                textWrap: "nowrap",
              }}
            >
              <UploadedFileWidget file_id={file.id} />
            </span>
            <IconButton
              onClick={() => {
                setFile(undefined);
              }}
            >
              <ClearIcon />
            </IconButton>
          </>
        ) : (
          <UploadFileButton
            disableSuccessSnackBar
            label="Join File"
            tooltip="Set the file of this new inbox entry"
            onUploaded={setFile}
          />
        )
      ) : (
        <></>
      )}
      &nbsp;
      {/* Date input */}
      <DateInput
        ref={dateInputRef}
        autoFocus
        editable
        style={{ flex: 1, maxWidth: "140px" }}
        value={movTime}
        onValueChange={setMovTime}
      />
      &nbsp;
      {/* Label input */}
      <TextInput
        editable
        placeholder={`${firstLetterUppercase(entity)} label`}
        value={label}
        onValueChange={setLabel}
        style={{ flex: 1 }}
        size={
          p.isInbox
            ? ServerApi.Config.constraints.inbox_entry_label
            : ServerApi.Config.constraints.movement_label
        }
      />
      &nbsp;
      {/* Amount input */}
      <AmountInput
        editable
        placeholder="Amount"
        style={{ flex: 1, maxWidth: "110px" }}
        value={amount ?? 0}
        onValueChange={setAmount}
      />
      {/* Submit button */}
      <Tooltip title={`Add new ${entity}`}>
        <IconButton onClick={submit}>
          <AddIcon />
        </IconButton>
      </Tooltip>
      <input type="submit" style={{ display: "none" }} />
    </form>
  );
}
