"use client";
import {
  Button,
  ButtonGroup,
  Grid,
  Input,
  Slider,
  Stack,
  styled,
  TextField,
  Typography,
} from "@mui/material";
import React from "react";
import { StripBusOutput, StripBusOutputEvent } from "./StripBusOutput";
import { EventCounter } from "@/utils/EventCounter";

export interface BusProps {
  values?: Partial<Omit<BusState, StateDefaultValueException>>;
  width: number;
  name: string;
  onChange: (event: BusEvent) => any;
}

type StateDefaultValueException = "";

export interface BusState {
  gain: number;
  muted: boolean;
  selected: boolean;
}

export type BusEvent = BusMuted | BusGainChanged | BusSelectToggle;

export interface BusGainChanged {
  type: "StripGainChanged";
  gain: number;
}
export interface BusMuted {
  type: "StripMuted";
  muted: boolean;
}
export interface BusSelectToggle {
  type: "BusSelectToggle";
  selected: boolean;
}

export class Bus extends React.Component<BusProps, BusState> {
  private eventCounter = new EventCounter<"onSliderResetDefaults">();
  private defaultValues: Omit<BusState, StateDefaultValueException> = {
    gain: 0,
    selected: false,
    muted: false,
  };
  slider = styled(Slider)(({ theme }) => ({
    "& .MuiSlider-valueLabel": {
      top: 0,
      fontFamily: '"Roboto","Helvetica","Arial",sans-serif',
      fontWeight: 400,
      fontSize: "0.75rem",
      width:"4em",
      letterSpacing: "0.03333em",
      backgroundColor: "unset",
      color: theme.palette.text.primary,
      "&::before": {
        display: "none",
      },
      "& *": {
        background: "transparent",
        color: theme.palette.mode === "dark" ? "#fff" : "#000",
      },
    },
  }));
  constructor(props: BusProps) {
    super(props);
    let { values: initialValues } = props;
    const getValue = (name: keyof typeof this.defaultValues) => {
      if (initialValues === undefined) return this.defaultValues[name];
      return initialValues[name] !== undefined
        ? this.defaultValues[name]
        : initialValues[name];
    };
    this.state = {
      ...(Object.fromEntries(
        Object.entries(this.defaultValues).map(([name]) => [
          name,
          getValue(name as keyof typeof this.defaultValues) as any,
        ])
      ) as Omit<BusState, StateDefaultValueException>),
    };
    this.eventCounter.on({
      callback: this.onResetDefaults.bind(this),
      count: 2,
      name: "onSliderResetDefaults",
    });
  }
  onResetDefaults() {
    this.setState({ gain: this.defaultValues.gain });
  }
  onKeyDown(event: React.KeyboardEvent) {
    console.log(event);

    if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
      event.preventDefault();
    }
  }
  onGainChange(event: Event | React.ChangeEvent<HTMLInputElement>) {
    let changedGain = parseFloat((event.target as HTMLInputElement).value);
    if (changedGain > 12) changedGain = 12;
    else if (changedGain < -60) changedGain = -60;
    this.setState({
      gain: changedGain,
    });
    this.props.onChange({
      type: "StripGainChanged",
      gain: changedGain,
    });
  }
  onStripWheel(event: React.WheelEvent) {
    console.log(event);
  }
  onSliderClick(event: React.MouseEvent) {
    this.stopPropagation(event);
    this.eventCounter.emit("onSliderResetDefaults");
  }
  onMuteToggle(event: React.MouseEvent) {
    this.stopPropagation(event);
    this.setState(
      (state) => ({ muted: !state.muted }),
      () => {
        this.props.onChange({ type: "StripMuted", muted: this.state.muted });
      }
    );
  }
  onSelectToggle(event: React.MouseEvent) {
    this.stopPropagation(event);
    this.setState(
      (state) => ({ selected: !state.selected }),
      () => {
        this.props.onChange({
          type: "BusSelectToggle",
          selected: this.state.selected,
        });
      }
    );
  }
  stopPropagation(event: Event | React.MouseEvent) {
    if (event instanceof Event) event.stopImmediatePropagation();
    else event.nativeEvent.stopImmediatePropagation();
  }
  render() {
    return (
      <>
        <Stack
          alignItems={"center"}
          direction={"row"}
          spacing={0}
          sx={{ width: "inherit" }}
        >
          {this.props.width > 600 ? (
            <TextField
              // inputProps={{
              //   "aria-labelledby": "input-slider",
              //   itemType: "number",
              //   style:{padding: 0}
              // }}
              value={this.state.gain}
              onWheel={(e) => this.onStripWheel(e)}
              onClick={(e) => this.stopPropagation(e)}
              onChange={(e) => this.onGainChange(e as unknown as Event)}
              size="small"
              label={this.props.name}
              type="number"
              variant="outlined"
              sx={{ minWidth: "100px", maxWidth: "100px" }}
            />
          ) : (
            <Typography variant="caption">{this.props.name}</Typography>
          )}

          {/* {this.props.width <= 600 && (
            <Typography
              position={"absolute"}
              paddingInlineStart={"10rem"}
              paddingBlockEnd={"2rem"}
              fontSize={"0.6rem"}
              width={"fit-content"}
              variant="caption"
            >
              {this.state.gain}dB
            </Typography>
          )} */}
          <this.slider
            sx={{
              // margin: "5px",
              marginInline: "10px",
            }}
            valueLabelFormat={(e) => `${e} dB`}
            // orientation="vertical"
            color={
              (this.state.gain > 0 && this.state.gain < 12 && "warning") ||
              (this.state.gain >= 12 && "error") ||
              (this.state.gain < 0 && "info") ||
              "primary"
            }
            defaultValue={0.0}
            step={0.1}
            min={-60}
            max={12}
            value={this.state.gain}
            valueLabelDisplay={this.props.width > 600 ? "off" : "on"}
            onChange={(e) => this.onGainChange(e)}
            onClick={(e) => this.onSliderClick(e)}
          />

          <ButtonGroup>
            <Button
              onClick={(e) => this.onMuteToggle(e)}
              variant={this.state.muted ? "contained" : "outlined"}
              color={"error"}
            >
              Mute
            </Button>
            <Button
              onClick={(e) => this.onSelectToggle(e)}
              sx={{}}
              variant={this.state.selected ? "contained" : "outlined"}
              color={"warning"}
            >
              S
            </Button>
          </ButtonGroup>
        </Stack>
        {/* <Stack>
            <ButtonGroup orientation="vertical">
              {[
                ...Array(this.props.physicalBuses + this.props.virtualBuses),
              ].map((_v, i) => (
                <StripBusOutput
                  key={`${i < this.props.physicalBuses ? "a" : "b"}${
                    i < this.props.physicalBuses
                      ? i
                      : i - this.props.physicalBuses
                  }`}
                  id={
                    i < this.props.physicalBuses
                      ? i
                      : i - this.props.physicalBuses
                  }
                  isVirtual={i < this.props.physicalBuses ? false : true}
                  onChange={(ev) => this.onBusChange(ev)}
                  default={{ enabled: this.state.buses[i] }}
                />
              ))}
            </ButtonGroup>
          </Stack> */}
      </>
    );
  }
}
