import logWebUserEvent from '@/logging/logWebUserEvent';

import { StudioContextType } from '../StudioContext';
import {
  setSongFadeInBeats,
  setSongFadeOutBeats,
} from '../actions/updateSongFades';
import getCanvasRelativeRect from '../getCanvasRelativeRect';
import { inFlightDragKeys } from '../hooks/useInFlightDrags';
import { getSongEndBeats, getSongStartBeats } from '../selectors';
import { makeFadeInRegions, makeFadeOutRegions } from './makeFadeRegions';

export default function makeSongFadeRegions(studioContext: StudioContextType) {
  const songEndBeats = getSongEndBeats(studioContext.state);
  const songStartBeats = getSongStartBeats(studioContext.state);

  const fadeOutCanvasX = studioContext.beatsToCanvasX(
    songEndBeats -
      (studioContext.state.songFadeOutBeats +
        studioContext.inFlightDrags.get(inFlightDragKeys.songFadeOut()))
  );

  const songStartCanvasX = studioContext.beatsToCanvasX(songStartBeats);
  const songEndCanvasX = studioContext.beatsToCanvasX(songEndBeats);
  const fadeInCanvasX = studioContext.beatsToCanvasX(
    songStartBeats +
      (studioContext.state.songFadeInBeats +
        studioContext.inFlightDrags.get(inFlightDragKeys.songFadeIn()))
  );

  const firstTrackDiv =
    studioContext.timelineController.trackHeadersRef.current[
      studioContext.state.tracks[0]?.id
    ] || null;

  if (!firstTrackDiv || !studioContext.state.tracks[0]) return [];

  const firstTrackRect = getCanvasRelativeRect(
    firstTrackDiv.getBoundingClientRect(),
    studioContext.timelineController.getWrapperRect()
  );

  const fadeOutHandleX = Math.min(fadeOutCanvasX + 49, songEndCanvasX - 15);
  const fadeInHandleX = Math.max(fadeInCanvasX - 49, songStartCanvasX + 15);
  const fadeHandleY = firstTrackRect.bottom - 15;

  return [
    ...(studioContext.state.songFadeInBeats > 0
      ? makeFadeInRegions(
          studioContext,
          studioContext.state.tracks[0].id,
          getSongStartBeats(studioContext.state),
          studioContext.state.songFadeInBeats,
          (delta) => {
            studioContext.inFlightDrags.update(
              inFlightDragKeys.songFadeIn(),
              delta
            );
            studioContext.playbackController.setFadeInBeats(
              studioContext.state.songFadeInBeats + delta
            );
          },
          (delta) => {
            studioContext.inFlightDrags.finishAll();
            studioContext.setState(setSongFadeInBeats((prev) => prev + delta));
            studioContext.playbackController.setFadeInBeats(
              studioContext.state.songFadeInBeats + delta
            );
          },
          inFlightDragKeys.songFadeIn()
        )
      : []),
    ...(studioContext.state.songFadeOutBeats > 0
      ? makeFadeOutRegions(
          studioContext,
          studioContext.state.tracks[0].id,
          getSongEndBeats(studioContext.state),
          studioContext.state.songFadeOutBeats,
          (delta) => {
            studioContext.inFlightDrags.update(
              inFlightDragKeys.songFadeOut(),
              delta
            );
            studioContext.playbackController.setFadeOutBeats(
              studioContext.state.songFadeOutBeats + delta
            );
          },
          (delta) => {
            studioContext.inFlightDrags.finishAll();
            studioContext.setState(setSongFadeOutBeats((prev) => prev + delta));
            studioContext.playbackController.setFadeOutBeats(
              studioContext.state.songFadeOutBeats + delta
            );
          },
          inFlightDragKeys.songFadeOut()
        )
      : []),

    {
      touchTarget: {
        bounds: {
          left: fadeInHandleX - 15,
          top: fadeHandleY - 15,
          right: fadeInHandleX + 45,
          bottom: fadeHandleY + 15,
        },
        hoverCursor: 'pointer',
        hoverGroup: inFlightDragKeys.songFadeIn(),
        onMouseDown: () => {
          const enabledBefore = studioContext.state.songFadeInBeats > 0;
          const songFadeInBeats =
            studioContext.state.songFadeInBeats > 0 ? 0 : 8;
          const enabledAfter = songFadeInBeats > 0;
          studioContext.setState(setSongFadeInBeats(songFadeInBeats));
          studioContext.playbackController.setFadeInBeats(songFadeInBeats);

          logWebUserEvent({
            actionName: 'EditV3FadeInToggled',
            context: {
              editSessionId: studioContext.editSessionId,
              editingClipId:
                studioContext.state.editClipId || 'MISSING_EDIT_CLIP_ID',
              enabledBefore,
              enabledAfter,
            },
          });
        },
      },
      renderTop: (ctx: CanvasRenderingContext2D, hovered: boolean) => {
        ctx.fillStyle = `rgba(255, 255, 255, ${
          studioContext.state.songFadeInBeats > 0 ? 1 : hovered ? 0.75 : 0.5
        })`;
        ctx.strokeStyle =
          studioContext.state.songFadeInBeats > 0
            ? 'rgba(0, 0, 0, 1.0)'
            : 'rgba(0, 0, 0, 0.35)';
        ctx.beginPath();
        ctx.roundRect(fadeInHandleX - 9, fadeHandleY - 10, 54, 20, 10);
        ctx.fill();
        ctx.beginPath();
        ctx.moveTo(fadeInHandleX + 5, fadeHandleY - 3);
        ctx.lineTo(fadeInHandleX + 2, fadeHandleY - 3);
        ctx.lineTo(fadeInHandleX - 2, fadeHandleY + 3);
        ctx.lineTo(fadeInHandleX - 5, fadeHandleY + 3);
        ctx.stroke();
        ctx.stroke();
        ctx.fillStyle = ctx.strokeStyle;
        ctx.font = '10px "Input Sans", monospace';
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        ctx.fillText('FADE', fadeInHandleX + 10, fadeHandleY + 1);
      },
    },

    {
      touchTarget: {
        bounds: {
          left: fadeOutHandleX - 45,
          top: fadeHandleY - 15,
          right: fadeOutHandleX + 15,
          bottom: fadeHandleY + 15,
        },
        hoverCursor: 'pointer',
        hoverGroup: inFlightDragKeys.songFadeOut(),
        onMouseDown: () => {
          const enabledBefore = studioContext.state.songFadeOutBeats > 0;
          const songFadeOutBeats =
            studioContext.state.songFadeOutBeats > 0 ? 0 : 8;
          const enabledAfter = songFadeOutBeats > 0;
          studioContext.setState(setSongFadeOutBeats(songFadeOutBeats));
          studioContext.playbackController.setFadeOutBeats(songFadeOutBeats);
          logWebUserEvent({
            actionName: 'EditV3FadeOutToggled',
            context: {
              editSessionId: studioContext.editSessionId,
              editingClipId:
                studioContext.state.editClipId || 'MISSING_EDIT_CLIP_ID',
              enabledBefore,
              enabledAfter,
            },
          });
        },
      },
      renderTop: (ctx: CanvasRenderingContext2D, hovered: boolean) => {
        ctx.fillStyle = `rgba(255, 255, 255, ${studioContext.state.songFadeOutBeats > 0 ? 1 : hovered ? 0.75 : 0.5})`;
        ctx.strokeStyle =
          studioContext.state.songFadeOutBeats > 0
            ? 'rgba(0, 0, 0, 1.0)'
            : 'rgba(0, 0, 0, 0.35)';
        ctx.beginPath();
        ctx.roundRect(fadeOutHandleX - 45, fadeHandleY - 10, 54, 20, 10);
        ctx.fill();
        ctx.beginPath();
        ctx.moveTo(fadeOutHandleX - 5, fadeHandleY - 3);
        ctx.lineTo(fadeOutHandleX - 2, fadeHandleY - 3);
        ctx.lineTo(fadeOutHandleX + 2, fadeHandleY + 3);
        ctx.lineTo(fadeOutHandleX + 5, fadeHandleY + 3);
        ctx.stroke();
        ctx.fillStyle = ctx.strokeStyle;
        ctx.font = '10px "Input Sans", monospace';
        ctx.textAlign = 'right';
        ctx.textBaseline = 'middle';
        ctx.fillText('FADE', fadeOutHandleX - 10, fadeHandleY + 1);
      },
    },
  ];
}
