import AddIcon from "@mui/icons-material/Add";
import {
  Fab,
  ListItem,
  ListItemButton,
  Paper,
  Tooltip,
  Typography,
} from "@mui/material";
import React from "react";
import { Movement, MovementApi } from "../api/MovementsApi";
import { UpdateMovementDialog } from "../dialogs/UpdateMovementDialog";
import { AsyncWidget } from "./AsyncWidget";
import { AccountInput } from "./forms/AccountInput";
import { AmountInput } from "./forms/AmountInput";
import { DateInput } from "./forms/DateInput";
import { TextInput } from "./forms/TextInput";
import { MovementWidget } from "./MovementWidget";

export function SelectMovementWidget(p: {
  value?: number;
  onChange: (movement: Movement) => void;
  initialValues?: {
    amount?: number;
    accountId?: number;
    time?: number;
    label?: string;
  };
}): React.ReactElement {
  const loadKey = React.useRef(1);

  const [amount, setAmount] = React.useState<number | undefined>(
    p.initialValues?.amount
  );
  const [accountId, setAccountId] = React.useState<number | undefined>(
    p.initialValues?.accountId
  );
  const [time, setTime] = React.useState<number | undefined>(
    p.initialValues?.time
  );
  const [label, setLabel] = React.useState<string | undefined>(
    p.initialValues?.label
  );

  const filters = {
    label: label,
    amount_min: amount ? amount - 0.5 : undefined,
    amount_max: amount ? amount + 0.5 : undefined,
    time_min: time ? time - 3600 * 24 : undefined,
    time_max: time ? time + 3600 * 24 : undefined,
    limit: 10,
  };

  const [list, setList] = React.useState<Movement[] | undefined>();

  const load = async () => {
    if (accountId)
      setList(await MovementApi.GetAccountMovements(accountId, filters));
    else setList(undefined);
  };

  const [creating, setCreating] = React.useState(false);

  const handleStartCreateNewMovement = () => {
    setCreating(true);
  };

  const handleCloseCreateNewMovement = () => {
    setCreating(false);
  };

  const handleCreatedNewMovement = (m: Movement) => {
    setAmount(m.amount);
    setAccountId(m.account_id);
    setTime(m.time);
    setLabel(m.label);
    p.onChange(m);
    loadKey.current += 1;
    setCreating(false);
  };

  return (
    <>
      <Paper
        style={{
          padding: "10px",
          flex: 1,
          display: "flex",
          flexDirection: "column",
        }}
      >
        <div
          style={{
            display: "flex",
            flexDirection: "row",
            alignItems: "center",
          }}
        >
          <AccountInput
            value={accountId}
            onChange={setAccountId}
            style={{ flex: 20 }}
          />
          <span style={{ flex: 1 }} />
          <AmountInput
            editable
            value={amount ?? 0}
            onValueChange={setAmount}
            label="Amount"
            placeholder="Amount"
            variant="outlined"
            style={{ height: "100%", flex: 20 }}
          />
          <span style={{ flex: 1 }} />
          <DateInput
            editable
            value={time}
            onValueChange={setTime}
            label="Date"
            style={{ flex: 20 }}
            variant="outlined"
          />
          <span style={{ flex: 1 }} />
          <TextInput
            editable
            value={label}
            onValueChange={setLabel}
            label="Label"
            variant="outlined"
            style={{ flex: 20 }}
          />
        </div>

        <div style={{ flex: 1 }}>
          <AsyncWidget
            loadKey={`${loadKey.current}/${accountId}/${JSON.stringify(
              filters
            )}`}
            load={load}
            errMsg="Failed to load the list of movements!"
            build={() => {
              if (list === undefined)
                return (
                  <Typography style={{ textAlign: "center", padding: "20px" }}>
                    Select an account to begin research.
                  </Typography>
                );
              if (list.length === 0)
                return (
                  <Typography style={{ textAlign: "center", padding: "20px" }}>
                    No result.
                  </Typography>
                );

              return (
                <>
                  {list.map((entry) => (
                    <ListItem key={entry.id}>
                      <ListItemButton
                        selected={entry.id === p.value}
                        onClick={() => {
                          p.onChange(entry);
                        }}
                      >
                        <MovementWidget movement={entry} />
                      </ListItemButton>
                    </ListItem>
                  ))}
                </>
              );
            }}
          />
        </div>

        <div style={{ textAlign: "right" }}>
          <Tooltip title="Create a new movement">
            <Fab
              color="primary"
              aria-label="Create a new movement"
              onClick={handleStartCreateNewMovement}
            >
              <AddIcon />
            </Fab>
          </Tooltip>
        </div>
      </Paper>
      {creating && accountId && (
        <UpdateMovementDialog
          open
          initial={{
            account_id: accountId,
            amount: amount ?? 0,
            checked: false,
            label: label ?? "",
            time: time ?? 0,
          }}
          onClose={handleCloseCreateNewMovement}
          onFinished={handleCreatedNewMovement}
        />
      )}
    </>
  );
}
