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

export interface StripProps {
  physicalBuses: number;
  virtualBuses: number;
  values?: Partial<StripState>;
  onChange: (event: StripEvent) => any;
}

export interface StripState {
  gain: number;
  outputBuses: boolean[];
  muted: boolean;
}

export type StripEvent = StripBusOutputChanged | StripMuted | StripGainChanged;

export interface StripBusOutputChanged extends StripBusOutputEvent {
  type: "StripBusOutputChanged";
}

export interface StripGainChanged {
  type: "StripGainChanged";
  gain: number;
}
export interface StripMuted {
  type: "StripMuted";
  muted: boolean;
}

export class Strip extends React.Component<StripProps, StripState> {
  constructor(props: StripProps) {
    super(props);
    const { values: initialValues } = props;
    const defaultValues: StripState = {
      gain: 0,
      outputBuses: [...Array(props.physicalBuses + props.virtualBuses)].map(
        (_v, k) => false
      ),
      muted: false,
    };
    const getValue = (name: keyof typeof defaultValues) => {
      if (initialValues === undefined) return defaultValues[name];
      return initialValues[name] !== undefined
        ? defaultValues[name]
        : initialValues[name];
    };
    this.state = Object.fromEntries(
      Object.entries(defaultValues).map(([name]) => [
        name,
        getValue(name as keyof typeof defaultValues) as any,
      ])
    ) as StripState;
  }
  onResetDefaults(e: React.MouseEvent) {
    e.stopPropagation();
    this.setState({ gain: 0 });
  }
  onKeyDown(event: React.KeyboardEvent) {
    console.log(event);

    if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
      event.preventDefault();
    }
  }
  onChange(event: React.ChangeEvent<HTMLInputElement>) {
    const multiplier = (event as unknown as React.KeyboardEvent).shiftKey
      ? 2
      : 1;
    const changedGain =
      parseFloat((event.target as HTMLInputElement).value) * multiplier;
    this.setState({
      gain: changedGain,
    });
    this.props.onChange({
      type: "StripGainChanged",
      gain: changedGain,
    });
  }
  onBusChange(event: StripBusOutputEvent) {
    const buses = this.state.outputBuses;
    buses[
      event.isVirtual ? this.props.physicalBuses + event.busId : event.busId
    ] = event.enabled;
    this.setState({
      outputBuses: buses,
    });
    this.props.onChange({
      type: "StripBusOutputChanged",
      busId: event.busId,
      isVirtual: event.isVirtual,
      enabled: event.enabled,
    });
  }
  onStripWheel(event: React.WheelEvent) {
    console.log(event);
  }
  onMuteToggle() {
    this.setState(
      (state) => ({ muted: !state.muted }),
      () => {
        this.props.onChange({ type: "StripMuted", muted: this.state.muted });
      }
    );
  }
  render() {
    return (
      <>
        <Stack direction={"row"}>
          <Stack alignItems={"center"} style={{ maxWidth: "min-content" }}>
            <Input
              inputProps={{
                "aria-labelledby": "input-slider",
                itemType: "number",
              }}
              value={this.state.gain}
              onWheel={(ev) => this.onStripWheel(ev)}
              size="small"
              sx={{ marginInline: "5px" }}
            />
            <Slider
              sx={{
                margin: "5px",
                marginBlock: "15px",
              }}
              orientation="vertical"
              defaultValue={0.0}
              step={0.1}
              min={-60}
              max={12}
              value={this.state.gain}
              aria-label="Temperature"
              onChange={(ev) =>
                this.onChange(
                  ev as unknown as React.ChangeEvent<HTMLInputElement>
                )
              }
              onKeyDown={(ev) => this.onKeyDown(ev)}
            />

            <Button
              onClick={() => this.onMuteToggle()}
              variant={this.state.muted ? "contained" : "outlined"}
              color={"error"}
              style={{ paddingInline: "0px", maxWidth: "5px" }}
              size="large"
            >
              Mute
            </Button>
          </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.outputBuses[i] }}
                />
              ))}
            </ButtonGroup>
          </Stack>
        </Stack>
      </>
    );
  }
}
