import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
} from "@mui/material";
import React from "react";
import { Movement, MovementApi, MovementUpdate } from "../api/MovementsApi";
import { ServerApi } from "../api/ServerApi";
import { useAccounts } from "../hooks/AccountsListProvider";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { AccountInput } from "../widgets/forms/AccountInput";
import { AmountInput } from "../widgets/forms/AmountInput";
import { DateInput } from "../widgets/forms/DateInput";
import { TextInput } from "../widgets/forms/TextInput";

export function UpdateMovementDialog(p: {
  open: boolean;
  updateId?: number;
  initial: MovementUpdate;
  onClose: () => void;
  onFinished: (m: Movement) => void;
}): React.ReactElement {
  const alert = useAlert();
  const snackbar = useSnackbar();
  const loadingMessage = useLoadingMessage();
  const accounts = useAccounts();

  const [movement, setMovement] = React.useState(p.initial);

  const style: React.CSSProperties = { width: "100%", marginBottom: "15px" };

  const canSubmit =
    movement.amount !== 0 &&
    movement.account_id &&
    movement.time !== 0 &&
    movement.label.length > 0;

  const handleSubmit = async () => {
    try {
      loadingMessage.show(
        `${p.updateId ? "Updating" : "Creating"} the movement...`
      );

      let res: Movement;

      if (p.updateId) {
        res = await MovementApi.Update({ ...movement, id: p.updateId });
      } else {
        res = await MovementApi.Create(movement);
      }

      accounts.reloadBalances();

      snackbar("The movement was successfully saved!");

      p.onFinished(res);
    } catch (e) {
      console.error("Failed to save movement!", e);
      alert(`Failed to ${p.updateId ? "update" : "create"} movement! ${e}`);
    } finally {
      loadingMessage.hide();
    }
  };

  return (
    <Dialog open={p.open} onClose={p.onClose}>
      <DialogTitle>
        {p.updateId ? `Update a movement` : `Create a movement`}
      </DialogTitle>
      <DialogContent>
        {/* Account */}
        <AccountInput
          value={movement.account_id}
          label="Amount"
          variant="standard"
          style={style}
          onChange={(a) => {
            setMovement((m) => {
              return {
                ...m,
                account_id: a,
              };
            });
          }}
        />
        {/* Date input */}
        <DateInput
          autoFocus
          editable
          label="Movement date"
          value={movement.time}
          style={style}
          onValueChange={(t) => {
            setMovement((m) => {
              return {
                ...m,
                time: t ?? 0,
              };
            });
          }}
        />
        {/* Label input */}
        <TextInput
          editable
          placeholder={`Movement label`}
          label="Movement label"
          value={movement.label}
          onValueChange={(l) => {
            setMovement((m) => {
              return {
                ...m,
                label: l ?? "",
              };
            });
          }}
          size={ServerApi.Config.constraints.movement_label}
        />
        {/* Amount input */}
        <AmountInput
          editable
          placeholder="Amount"
          label="Amount"
          style={style}
          value={movement.amount}
          onValueChange={(l) => {
            setMovement((m) => {
              return {
                ...m,
                amount: l,
              };
            });
          }}
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={p.onClose}>Cancel</Button>
        <Button onClick={handleSubmit} autoFocus disabled={!canSubmit}>
          {p.updateId ? `Update` : `Create`}
        </Button>
      </DialogActions>
    </Dialog>
  );
}
