import { CanvasRegion } from '@/components/edit2025/canvasRenderer/CanvasRenderer';

import { StudioContextType } from '../StudioContext';
import getCanvasRelativeRect from '../getCanvasRelativeRect';
import { getEffectivelyMutedTracks } from '../selectors';

let lastHoverStartTime = Infinity;
let lastHoverEndTime = Infinity;
let wasHovered = false;

const MAX_OPACITY = 0.8;

const ENABLE_CONTEXT_WINDOW_PREVIEW = false;

export default function makeStudioIncludedContextArrangementsRegions(
  studioContext: StudioContextType
): CanvasRegion[] {
  if (!ENABLE_CONTEXT_WINDOW_PREVIEW) return [];
  const hovered =
    studioContext.timelineController.contextualGenerateButtonHoveredRef.current;
  let hoverOpacity = 0;

  if (wasHovered && !hovered) {
    lastHoverEndTime = Date.now();
    wasHovered = false;
  }

  if (!wasHovered && hovered) {
    lastHoverStartTime = Date.now();
    wasHovered = true;
  }

  if (hovered && Number.isFinite(lastHoverStartTime)) {
    hoverOpacity = Math.min(
      MAX_OPACITY,
      ((Date.now() - lastHoverStartTime) / 200) * MAX_OPACITY
    );
  } else if (!hovered && Number.isFinite(lastHoverEndTime)) {
    hoverOpacity = Math.max(
      0,
      (1 - (Date.now() - lastHoverEndTime) / 200) * MAX_OPACITY
    );
  } else {
    return [];
  }

  if (hoverOpacity < MAX_OPACITY && hoverOpacity > 0) {
    studioContext.timelineController.frameCountRef.current++;
  }

  const effectivelyMutedTracks = getEffectivelyMutedTracks(studioContext.state);
  const effectiveSelection = studioContext.getEffectiveSelection();
  const contextStartBeats =
    effectiveSelection.startBeats - studioContext.contextBeforeBeats;
  const contextEndBeats =
    effectiveSelection.endBeats + studioContext.contextAfterBeats;
  const contextStartX = studioContext.beatsToCanvasX(contextStartBeats);
  const contextEndX = studioContext.beatsToCanvasX(contextEndBeats);
  const wrapperRect = studioContext.timelineController.getWrapperRect();
  return studioContext.state.tracks.map((track) => {
    const trackId = track.id;
    const trackHeader =
      studioContext.timelineController.trackHeadersRef.current[trackId];
    if (!trackHeader) return {};

    const trackRect = getCanvasRelativeRect(
      trackHeader.getBoundingClientRect(),
      wrapperRect
    );

    if (trackRect.top > wrapperRect.height) return {};
    if (trackRect.bottom < 0) return {};
    if (effectivelyMutedTracks[trackId]) {
      return {
        renderTop: (ctx: CanvasRenderingContext2D) => {
          ctx.fillStyle = `rgba(16, 16, 18, ${hoverOpacity})`;
          ctx.beginPath();
          ctx.rect(
            0,
            trackRect.top,
            wrapperRect.width,
            trackRect.bottom - trackRect.top
          );
          ctx.closePath();
          ctx.fill();

          ctx.save();
          ctx.fillStyle = `rgba(255,255,255,${hoverOpacity})`;
          ctx.font = '10px "Input Sans", monospace';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          ctx.fillText(
            'TRACK MUTED',
            contextStartX + (contextEndX - contextStartX) / 2,
            trackRect.top + trackRect.height / 2
          );
          ctx.restore();
        },
      };
    } else {
      return {
        renderTop: (ctx: CanvasRenderingContext2D) => {
          ctx.fillStyle = `rgba(16, 16, 18, ${hoverOpacity})`;
          ctx.fillRect(
            0,
            trackRect.top,
            contextStartX,
            trackRect.bottom - trackRect.top
          );
          ctx.fillRect(
            contextEndX,
            trackRect.top,
            wrapperRect.width - contextEndX,
            trackRect.bottom - trackRect.top
          );
          ctx.strokeStyle = `rgba(255,255,255,${hoverOpacity})`;
          ctx.strokeRect(
            contextStartX,
            trackRect.top - 1,
            contextEndX - contextStartX,
            trackRect.bottom - trackRect.top + 2
          );
          ctx.save();
          ctx.fillStyle = `rgba(255,255,255,${hoverOpacity})`;
          ctx.font = '10px "Input Sans", monospace';
          ctx.textAlign = 'right';
          ctx.textBaseline = 'middle';
          ctx.fillText(
            'START',
            contextStartX - 10,
            trackRect.top + trackRect.height / 2
          );
          ctx.textAlign = 'left';
          ctx.textBaseline = 'middle';
          ctx.fillText(
            'END',
            contextEndX + 10,
            trackRect.top + trackRect.height / 2
          );
          ctx.restore();
        },
      };
    }
  });
}
