import { gsap } from '@/lib/usePluggedGSAP';
import { court, darkLine, lightPastelBlue, lightSmoke, moss, standardGrey } from '@/styles/colors';
import styled from '@emotion/styled';
import CursorIcon from '../icons/Cursor.svg';
import RegenerateIcon from '../icons/Regenerate.svg';

import { useCallback } from 'react';
import InterfaceAnimation from './InterfaceAnimation';

const ComposerInterface = styled.div`
  width: 50rem;
  background-color: ${standardGrey};
  border-radius: 0.7rem;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  font-size: 1.8rem;
  font-family: Architekt;
  color: ${darkLine};
  font-weight: bold;
  position: relative;
`;

const ComposerHeader = styled.header`
  padding: 1.8rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
`;

const Title = styled.div``;

const TrackName = styled.span`
  color: ${lightPastelBlue};
`;

const ModePicker = styled.div`
  border-radius: 0.4rem;
  border: 1px solid ${lightSmoke};
  padding: 1.3rem 1.8rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 14rem;
  position: relative;
  &:after {
    content: '';
    display: block;
    position: relative;
    transform: rotate(45deg);
    margin-top: -0.3rem;
    width: 0.8rem;
    height: 0.8rem;
    border-right: 1px solid ${darkLine};
    border-bottom: 1px solid ${darkLine};
  }
`;

const OutputPreview = styled.div`
  border-top: 1px solid ${darkLine};
  border-bottom: 1px solid ${darkLine};
  height: 10rem;
  position: relative;
`;

const Ruler = styled.div`
  display: flex;
  position: absolute;
  bottom: 100%;
  left: 1.8rem;
  right: calc(1.8rem - 3px);
  justify-content: space-between;
  align-items: flex-end;
`;

const Tick = styled.div`
  border-left: 1px solid ${darkLine};
  height: 0.4rem;
  position: relative;
  width: 1px;
  flex-grow: 1;
  flex-shrink: 0;
  &:after {
    content: '';
    display: block;
    position: absolute;
    top: 100%;
    bottom: -10rem;
    left: -1px;
    border-left: 1px dashed ${darkLine};
    opacity: 0.15;
  }
`;

const BigTick = styled(Tick)`
  height: 1rem;
  font-size: 0.9rem;
  color: ${darkLine};
  padding-left: 0.4rem;
  span {
    position: relative;
    bottom: 0.2rem;
  }
`;

const OutputNotes = styled.div`
  position: absolute;
  top: 0;
  bottom: 0;
  left: 1.8rem;
  right: 1.8rem;
  display: flex;
  justify-content: stretch;
  align-items: stretch;
  color: ${darkLine};
`;

const Options = styled.div`
  padding: 1.8rem;
`;

const Suggestions = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1.3rem;
  height: 10rem;
  margin-top: 1.8rem;
`;

const Suggestion = styled.div`
  border-radius: 0.4rem;
  background-color: ${darkLine};
  color: ${standardGrey};
  position: relative;
`;

const Toggles = styled.div`
  margin-top: 1.8rem;
  display: grid;
  grid-template-columns: auto auto auto auto;
`;

const Toggle = styled.div`
  display: flex;
  font-family: Montreal;
  font-weight: normal;
  align-items: center;
  &:before {
    content: '';
    display: block;
    border: 1px solid ${darkLine};
    opacity: 0.5;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 0.2rem;
    margin-right: 1rem;
  }
`;

const Prompt = styled.div`
  font-family: Montreal;
  font-weight: normal;
  border-top: 1px solid ${darkLine};
  padding: 1.8rem;
  border-bottom: 1px solid ${darkLine};
  opacity: 0.5;
`;

const Buttons = styled.div`
  padding: 1.8rem;
  display: flex;
  justify-content: space-between;
`;

const RegenerateButton = styled.div`
  border-radius: 0.4rem;
  background-color: ${lightPastelBlue};
  color: ${standardGrey};
  padding: 1.8rem;
  width: 18rem;
  text-align: center;
  img {
    transform: scale(1.5);
    margin-right: 1rem;
    margin-bottom: -0.2rem;
  }
`;

const DoneButton = styled.div`
  border-radius: 0.4rem;
  color: ${darkLine};
  border: 1px solid ${darkLine};
  padding: 1.8rem;
  width: 18rem;
  text-align: center;
`;

const NoteContainer = styled.div`
  position: relative;
  height: 100%;
  width: 100%;
`;

const Progress = styled.div<{ green?: boolean }>`
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  background-color: ${({ green }) => (green ? `rgba(23, 112, 108, 0.5)` : `rgba(0, 0, 0, 0.2)`)};
  width: 0%;
`;

const Note = styled.div<{ set: number; timingOffset: number }>`
  position: absolute;
  height: 3px;
  background-color: currentColor;
  transform-origin: 0 0;
  .active-set-${({ set }) => set} & {
    transform: scaleX(1);
  }
  transform: scaleX(0);
  transition: transform 0.1s ease ${({ timingOffset }) => timingOffset}s;
`;

const OutputBar = styled.div`
  position: relative;
  height: 100%;
  width: 25%;
  color: ${court};
`;

const Cursor = styled.div`
  position: absolute;
  top: 50%;
  left: 50%;
  transform: scale(1.5);
  z-index: 2;
`;

const chordSets = [
  [[0, 2], [], [1, 3, 5], [], [1, 3, 5], [], [2, 4], []],
  [[0, 2], [1], [1, 5], [2, 4]],
  [[1, 6], [], [4, 6], [4, 6], [2, 6], [], [4, 6], [4, 6]],

  // 3-5: mono
  [[3], [2], [4], [3], [1], [0], [4], [1]],
  [[3], [3], [2], [4], [3], [3], [1], [1]],
  [[0], [2], [3], [5], [2], [3], [5], [6]],
];

const NoteDisplay = ({ dataNotes, className }: { dataNotes: string; className?: string }) => {
  return (
    <NoteContainer data-notes={dataNotes} className={className}>
      {chordSets.map((chordSet, i) =>
        chordSet.map((chord, j) =>
          chord.map((note, k) => (
            <Note
              set={i}
              key={`${i}-${j}-${k}`}
              timingOffset={j * 0.02 + k * 0.02}
              style={{
                width: `${100 / chordSet.length}%`,
                left: `${(j * 100) / chordSet.length}%`,
                bottom: `${((note + 0.5) / 7) * 100}%`,
              }}
            />
          ))
        )
      )}
    </NoteContainer>
  );
};

const ModePickerDropdown = styled(ModePicker)`
  position: absolute;
  top: -1px;
  left: -1px;
  right: 0;
  z-index: 1;
  background-color: ${standardGrey};
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  padding: 0;
  overflow: hidden;

  opacity: 0;
  height: 0rem;

  &:after {
    display: none;
  }
  &:hover & {
    display: flex;
  }
`;

const ModeOption = styled.div`
  padding: 1.3rem 1.8rem;
  background: ${standardGrey};
`;

const ComposerInterfaceAnimation = () => {
  const animate = useCallback((animationContent: HTMLDivElement) => {
    const c = (selector: string) => animationContent.querySelectorAll(selector);
    const BAR_PLAYBACK_DURATION = 1;
    const timeline = gsap.timeline({
      repeat: -1,
    });
    timeline
      .to(c('.cursor'), { left: '10%', top: '90%', duration: 0 })
      .delay(0.5)
      .to(c('.cursor'), { left: '20%', top: '55%', duration: 0.25 })
      .to(c('[data-notes=b1]'), { className: 'active-set-0', color: moss, duration: 0 })
      .to(c('.s1'), { background: court, color: darkLine, duration: 0 })
      .to(c('.s1p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.b1p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s1'), { background: lightPastelBlue, duration: 0 }, '+=0.25')
      .to(c('.s1p'), { width: 0, duration: 0 })
      .to(c('.s1'), { background: court, color: darkLine, duration: 0.25 })
      .to(c('.s1'), { background: '', color: '', duration: 0 })
      .to(c('.b1p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('[data-notes=b1]'), { color: court, duration: 0 })
      .to(c('[data-notes=s1]'), { className: 'active-set-1', duration: 0 })
      .to(c('[data-notes=s2]'), { className: 'active-set-2', duration: 0 })
      .to(c('[data-notes=s3]'), { className: 'active-set-0', duration: 0 })

      .to(c('.s1p'), { width: '0%', duration: 0, ease: 'none' }, '+=0.5')
      .to(c('.cursor'), { left: '45%', top: '53%', duration: 0.25 })
      .to(c('.b2p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('.s1'), { background: '', color: '', duration: 0 })
      .to(c('[data-notes=b2]'), { className: 'active-set-2', color: moss, duration: 0 })
      .to(c('.s2'), { background: court, color: darkLine, duration: 0 })
      .to(c('.s2p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.b2p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s2'), { background: lightPastelBlue, duration: 0 }, '+=0.25')
      .to(c('.s2p'), { width: 0, duration: 0 })
      .to(c('.s2'), { background: court, color: darkLine, duration: 0.25 })
      .to(c('.s2'), { background: '', color: '', duration: 0 })
      .to(c('.b2p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('[data-notes=b2]'), { color: court, duration: 0 })
      .to(c('[data-notes=s1]'), { className: 'active-set-2', duration: 0 })
      .to(c('[data-notes=s2]'), { className: 'active-set-0', duration: 0 })
      .to(c('[data-notes=s3]'), { className: 'active-set-1', duration: 0 })

      .to(c('.cursor'), { left: '22%', top: '57%', duration: 0.25 }, '+=0.5')
      .to(c('.s1'), { background: court, color: darkLine, duration: 0 })
      .to(c('[data-notes=b3]'), { className: 'active-set-2', color: moss, duration: 0 }, '<')
      .to(c('.b3p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s1p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')

      .to(c('.cursor'), { left: '80%', top: '10%', duration: 0.25 }, '+=0.5')
      .to(c('[data-notes=b3]'), { className: 'active-set-none', duration: 0 })
      .to(c('.s1'), { background: '', color: '', duration: 0 }, '<')
      .to(c('.b3p'), { width: '0%', duration: 0, ease: 'none' }, '<')
      .to(c('.s1p'), { width: '0%', duration: 0, ease: 'none' }, '<')
      .to(c('.mode-picker-dropdown'), { opacity: 1, height: '20rem', duration: 0.25 })
      .to(c('.cursor'), { left: '80%', top: '25%', duration: 0.25 }, '+=0.25')
      .to(c('.mode-picker-melody'), { background: lightPastelBlue, duration: 0 }, '+=0.25')
      .to(c('.current-mode'), { text: 'Melody', duration: 0 })
      .to(c('.mode-picker-melody'), { background: standardGrey, duration: 0.25 })
      .to(c('.mode-picker-dropdown'), { height: '0rem', opacity: 0, duration: 0.25 })
      .to(c('[data-notes=s1]'), { className: 'active-set-3', duration: 0 })
      .to(c('[data-notes=s2]'), { className: 'active-set-4', duration: 0 })
      .to(c('[data-notes=s3]'), { className: 'active-set-5', duration: 0 })

      .to(c('.cursor'), { left: '80%', top: '50%', duration: 0.25 }, '+=0.5')
      .to(c('.s3'), { background: court, color: darkLine, duration: 0 })
      .to(c('[data-notes=b3]'), { className: 'active-set-5', color: moss, duration: 0 }, '<')
      .to(c('.b3p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s3p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.cursor'), { left: '50%', top: '50%', duration: 0.25 }, '+=0.25')
      .to(c('.s3'), { background: '', color: '', duration: 0 })
      .to(c('.b3p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('.s3p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('[data-notes=b3]'), { className: 'active-set-none', duration: 0 })

      .to(c('.s2'), { background: court, color: darkLine, duration: 0 })
      .to(c('[data-notes=b3]'), { className: 'active-set-4', color: moss, duration: 0 }, '<')
      .to(c('.b3p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s2p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s2'), { background: lightPastelBlue, duration: 0 }, '+=0.25')
      .to(c('.s2p'), { width: 0, duration: 0 })
      .to(c('.s2'), { background: court, color: darkLine, duration: 0.25 })
      .to(c('.s2'), { background: '', color: '', duration: 0 })
      .to(c('.b3p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('[data-notes=b3]'), { color: court, duration: 0 })
      .to(c('[data-notes=s1]'), { className: 'active-set-5', duration: 0 })
      .to(c('[data-notes=s2]'), { className: 'active-set-3', duration: 0 })
      .to(c('[data-notes=s3]'), { className: 'active-set-4', duration: 0 })

      .to(c('.cursor'), { left: '53%', top: '51%', duration: 0.25 }, '+=0.5')
      .to(c('.s2'), { background: court, color: darkLine, duration: 0 })
      .to(c('[data-notes=b4]'), { className: 'active-set-3', color: moss, duration: 0 }, '<')
      .to(c('.b4p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s2p'), { width: '100%', duration: BAR_PLAYBACK_DURATION, ease: 'none' }, '<')
      .to(c('.s2'), { background: lightPastelBlue, duration: 0 }, '+=0.25')
      .to(c('.s2p'), { width: 0, duration: 0 })
      .to(c('.s2'), { background: court, color: darkLine, duration: 0.25 })
      .to(c('.s2'), { background: '', color: '', duration: 0 })
      .to(c('.b4p'), { width: '0%', duration: 0, ease: 'none' })
      .to(c('[data-notes=b4]'), { color: court, duration: 0 })
      .to(c('[data-notes]'), { className: '', duration: 0 }, '+=1')
      .to(c('[data-notes=s1]'), { className: 'active-set-0', duration: 0 })
      .to(c('[data-notes=s2]'), { className: 'active-set-1', duration: 0 })
      .to(c('[data-notes=s3]'), { className: 'active-set-2', duration: 0 })
      .to(c('.current-mode'), { text: 'Chords', duration: 0 });
  }, []);
  return (
    <InterfaceAnimation onAnimate={animate}>
      <ComposerInterface className="interface">
        <ComposerHeader>
          <Title>
            Track: <TrackName>MIDI Synth Seven</TrackName>
          </Title>
          <ModePicker>
            <span className="current-mode">Chords</span>
            <ModePickerDropdown className="mode-picker-dropdown">
              <ModeOption>Chords</ModeOption>
              <ModeOption>Beat</ModeOption>
              <ModeOption className="mode-picker-melody">Melody</ModeOption>
              <ModeOption>Freeform</ModeOption>
            </ModePickerDropdown>
          </ModePicker>
        </ComposerHeader>
        <OutputPreview>
          <Ruler>
            <BigTick>
              <span>1</span>
            </BigTick>
            <Tick />
            <Tick />
            <Tick />
            <BigTick>
              <span>2</span>
            </BigTick>
            <Tick />
            <Tick />
            <Tick />
            <BigTick>
              <span>3</span>
            </BigTick>
            <Tick />
            <Tick />
            <Tick />
            <BigTick>
              <span>4</span>
            </BigTick>
            <Tick />
            <Tick />
            <Tick />
            <BigTick style={{ flexGrow: 0, flexShrink: 1 }} />
          </Ruler>
          <OutputNotes>
            <OutputBar className="b1">
              <Progress green className="b1p" />
              <NoteDisplay dataNotes="b1" />
            </OutputBar>
            <OutputBar className="b2">
              <Progress green className="b2p" />
              <NoteDisplay dataNotes="b2" />
            </OutputBar>
            <OutputBar className="b3">
              <Progress green className="b3p" />
              <NoteDisplay dataNotes="b3" />
            </OutputBar>
            <OutputBar className="b4">
              <Progress green className="b4p" />
              <NoteDisplay dataNotes="b4" />
            </OutputBar>
          </OutputNotes>
        </OutputPreview>
        <Options>
          <Title>Options:</Title>
          <Suggestions>
            <Suggestion className="s1">
              <Progress className="s1p" />
              <NoteDisplay dataNotes="s1" className="active-set-0" />
            </Suggestion>
            <Suggestion className="s2">
              <Progress className="s2p" />
              <NoteDisplay dataNotes="s2" className="active-set-1" />
            </Suggestion>
            <Suggestion className="s3">
              <Progress className="s3p" />
              <NoteDisplay dataNotes="s3" className="active-set-2" />
            </Suggestion>
          </Suggestions>
          <Toggles>
            <Toggle>Go Wild</Toggle>
            <Toggle>Pitch Dir.</Toggle>
            <Toggle>New Rhythm</Toggle>
            <Toggle>2x</Toggle>
          </Toggles>
        </Options>
        <Prompt>Enter a prompt...</Prompt>
        <Buttons>
          <RegenerateButton>
            <img {...RegenerateIcon} />
            Regenerate
          </RegenerateButton>
          <DoneButton>Done</DoneButton>
        </Buttons>
        <Cursor className="cursor">
          <img {...CursorIcon} />
        </Cursor>
      </ComposerInterface>
    </InterfaceAnimation>
  );
};

export default ComposerInterfaceAnimation;
