import {
  Button,
  Checkbox,
  List,
  ListItemButton,
  ListItemText,
  Radio,
} from "@suid/material";
import type { mastodon } from "masto";
import {
  createEffect,
  createRenderEffect,
  createSignal,
  Index,
  Show,
  type Component,
} from "solid-js";
import BottomSheet, { type BottomSheetProps } from "~material/BottomSheet";
import Scaffold from "~material/Scaffold";
import { resolveCustomEmoji } from "../../masto/toot";
import "./TootPollDialog.css";

export type TootPollDialogPoll = {
  open?: boolean;
  options: Readonly<mastodon.v1.Poll["options"]>;
  initialVotes?: readonly number[];
  multiple?: boolean;

  onVote: [
    (
      status: mastodon.v1.Status,
      votes: readonly number[],
    ) => void | Promise<void>,
    mastodon.v1.Status,
  ];
  onClose?: BottomSheetProps["onClose"] &
    ((reason: "cancel" | "success") => void);
};

const TootPollDialog: Component<TootPollDialogPoll> = (props) => {
  const [votes, setVotes] = createSignal([] as readonly number[]);
  const [inProgress, setInProgress] = createSignal(false);

  createEffect(() => {
    setVotes(props.initialVotes || []);
  });

  const toggleVote = (i: number) => {
    if (props.multiple) {
      setVotes((o) => [...o.filter((x) => x === i), i]);
    } else {
      setVotes([i]);
    }
  };

  const sendVote = async () => {
    setInProgress(true);
    try {
      await props.onVote[0](props.onVote[1], votes());
    } catch (reason) {
      console.error(reason);
      props.onClose?.("cancel");
      return;
    } finally {
      setInProgress(false);
    }
    props.onClose?.("success");
  };

  return (
    <BottomSheet open={props.open} onClose={props.onClose} bottomUp>
      <Scaffold
        class="TootPollDialog"
        bottom={
          <div class="actions">
            <Button
              color="error"
              onClick={props.onClose ? [props.onClose, "cancel"] : undefined}
              disabled={inProgress()}
            >
              Cancel
            </Button>
            <Button onClick={sendVote} disabled={inProgress()}>
              Confirm
            </Button>
          </div>
        }
      >
        <List>
          <Index each={props.options}>
            {(option, index) => {
              return (
                <ListItemButton
                  onClick={[toggleVote, index]}
                  disabled={inProgress()}
                >
                  <ListItemText>
                    <span
                      ref={(e) =>
                        createRenderEffect(
                          () =>
                            (e.innerHTML = resolveCustomEmoji(
                              option().title,
                              option().emojis,
                            )),
                        )
                      }
                    ></span>
                  </ListItemText>

                  <Show
                    when={props.multiple}
                    fallback={<Radio checked={votes().includes(index)} />}
                  >
                    <Checkbox checked={votes().includes(index)} />
                  </Show>
                </ListItemButton>
              );
            }}
          </Index>
        </List>
      </Scaffold>
    </BottomSheet>
  );
};

export default TootPollDialog;
