import styled from '@emotion/styled';
import { useCallback, useRef, useState } from 'react';

import { useContext, useContextSelector } from '@/hooks/useContextSelector';
import { CloseIcon } from '@/icons';

import Button, { ButtonShape, ButtonVariant } from '../button/Button';
import { getPlaintextLyrics } from '../edit2025/lyrics/getPlaintextLyrics';
import {
  Divider,
  HorizontalPanelGroup,
  Panel,
  VerticalPanelGroup,
} from '../panelSystem/PanelSystem';
import SpinnerSVG from '../svg/SpinnerSVG';
import StudioContext from './StudioContext';
import StudioLyricsDisplayV2 from './StudioLyricsDisplayV2';
import {
  ThickGapHorizontalDivider,
  ThickGapVerticalDivider,
  oneFRPanelSize,
} from './StudioPanelUtilities';
import updateLyricsCorrectionsByClipId from './actions/updateLyricsCorrectionsByClipId';
import correctLyrics from './correctLyrics';
import makePanelSize from './makePanelSize';
import { getAlignedLyricsByTrackId, getAllUsedClipIds } from './selectors';
import useAlignedLyricsByClipId from './useAlignedLyricsByClipId';

const LyricsWrapper = styled.div`
  overflow-y: auto;
  flex-grow: 1;
  padding: 0 8px;
`;

const ContentWrapper = styled.div`
  max-width: 1200px;
  margin: 0 auto;
  height: 100%;
`;

const Textarea = styled.textarea`
  flex-grow: 1;
  padding: 10px;
  resize: none;
  width: 100%;
  height: 100%;
  font-size: 16px;
  line-height: 1.25;
  background-color: transparent;
  border-radius: 8px;
  color: var(--color-foreground-secondary);
  &:hover {
    cursor: text;
  }
  &:focus {
    outline: none;
  }
`;

const PanelContentWrapper = styled.div<{
  original?: boolean;
  outline?: boolean;
}>`
  border-radius: 10px;
  background-color: ${({ original }) =>
    original
      ? 'var(--color-background-glass-dense)'
      : 'var(--color-background-glass-thick)'};
  border: 1px solid
    ${({ original, outline }) =>
      original
        ? 'transparent'
        : outline
          ? 'var(--color-border-secondary)'
          : 'var(--color-border-primary)'};
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
`;

const PanelTitle = styled.h2`
  font-size: 20px;
  margin: 0;
  padding: 10px 10px 0 10px;
`;

export default function StudioLyricsCorrectionForm({
  onClose,
}: {
  onClose: () => void;
}) {
  const studioContext = useContext(StudioContext);
  const state = studioContext.state;
  const focusedTrackId = studioContext.state.selection.focusedTrackId;

  const allUsedClipIds = useContextSelector(StudioContext, (context) =>
    getAllUsedClipIds(context.state)
  );
  const lyricsCorrectionsByClipId = useContextSelector(
    StudioContext,
    (context) => context.state.lyricsCorrectionsByClipId
  );
  const alignedLyricsByClipId = useAlignedLyricsByClipId(
    allUsedClipIds,
    lyricsCorrectionsByClipId
  );

  const [isSaving, setIsSaving] = useState(false);

  const [correctedLyrics, setCorrectedLyrics] = useState(() =>
    focusedTrackId
      ? getPlaintextLyrics(
          getAlignedLyricsByTrackId({
            state,
            alignedLyricsByClipId,
          })[focusedTrackId]
        )
      : ''
  );

  const cancelledRef = useRef(false);

  const handleSaveChanges = useCallback(async () => {
    setIsSaving(true);
    cancelledRef.current = false;
    try {
      const newLyricsCorrectionsByClipId = await correctLyrics(
        studioContext,
        correctedLyrics
      );
      if (cancelledRef.current) {
        return;
      }
      studioContext.setState(
        updateLyricsCorrectionsByClipId(newLyricsCorrectionsByClipId)
      );

      onClose();
    } finally {
      setIsSaving(false);
    }
  }, [studioContext, correctedLyrics, onClose]);

  const [textareaFocused, setTextareaFocused] = useState(false);

  return (
    <ContentWrapper>
      <VerticalPanelGroup>
        <Panel size={makePanelSize(40)}>
          <div className='flex items-center justify-between gap-2'>
            <h1 className='pl-2 text-2xl'>Match Lyrics to Audio</h1>
            <Button
              variant={ButtonVariant.Primary}
              onClick={onClose}
              shape={ButtonShape.Pill}
              icon={<CloseIcon className='h-5 w-5' />}
            />
          </div>
        </Panel>
        <Divider influence='neither'>
          <ThickGapHorizontalDivider transparent />
        </Divider>
        <Panel size={oneFRPanelSize}>
          <HorizontalPanelGroup>
            <Panel size={oneFRPanelSize}>
              <PanelContentWrapper outline={textareaFocused}>
                <PanelTitle>Corrected Lyrics</PanelTitle>
                <LyricsWrapper>
                  {isSaving && (
                    <div className='absolute inset-0 z-10 flex flex-col items-center justify-center gap-2 bg-black/50 backdrop-blur-sm'>
                      <SpinnerSVG />
                      Matching lyrics timing to audio. This may take some time.
                      <Button
                        variant={ButtonVariant.Secondary}
                        onClick={() => {
                          cancelledRef.current = true;
                          setIsSaving(false);
                        }}
                      >
                        Cancel
                      </Button>
                    </div>
                  )}
                  <Textarea
                    disabled={isSaving}
                    autoFocus
                    value={correctedLyrics}
                    onChange={(e) => setCorrectedLyrics(e.target.value)}
                    onFocus={() => setTextareaFocused(true)}
                    onBlur={() => setTextareaFocused(false)}
                  />
                </LyricsWrapper>
              </PanelContentWrapper>
            </Panel>
            <Divider influence='both'>
              <ThickGapVerticalDivider transparent />
            </Divider>
            <Panel size={oneFRPanelSize}>
              <PanelContentWrapper original>
                <PanelTitle>Original Lyrics</PanelTitle>
                <LyricsWrapper>
                  <StudioLyricsDisplayV2 defaultSelectionBehavior />
                </LyricsWrapper>
              </PanelContentWrapper>
            </Panel>
          </HorizontalPanelGroup>
        </Panel>
        <Divider influence='neither'>
          <ThickGapHorizontalDivider transparent />
        </Divider>
        <Panel size={makePanelSize(40)}>
          <div className='flex justify-center gap-2'>
            <Button
              className='w-[130px]'
              disabled={isSaving}
              variant={ButtonVariant.Secondary}
              onClick={() => {
                onClose();
              }}
            >
              Cancel
            </Button>
            <Button
              className='w-[130px]'
              variant={ButtonVariant.Primary}
              onClick={handleSaveChanges}
              disabled={isSaving}
            >
              Save Changes
            </Button>
          </div>
        </Panel>
      </VerticalPanelGroup>
    </ContentWrapper>
  );
}
