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

import { StudioContextType } from '../StudioContext';
import { CLIP_CORNER_RADIUS } from '../constants';
import { defaultStudioTrackHeight } from '../createTrack';
import getCanvasRelativeRect from '../getCanvasRelativeRect';

export default function makeStudioDragPreviewRegions(
  studioContext: StudioContextType
): CanvasRegion[] {
  const dragState = studioContext.dragStateRef.current;
  if (!dragState || !dragState.active) return [];

  const result: CanvasRegion[] = [];
  dragState.insertionSpecs.forEach((spec) => {
    const trackId = spec.trackId;
    if (!trackId) return;
    const trackElement =
      studioContext.timelineController.trackHeadersRef.current[trackId];
    if (!trackElement) return;

    const timelineRect = studioContext.timelineController.getWrapperRect();
    const trackRect = getCanvasRelativeRect(
      trackElement.getBoundingClientRect(),
      timelineRect
    );

    const x = studioContext.beatsToCanvasX(spec.replacementStartBeats);
    const width = studioContext.beatsToCanvasX(spec.replacementEndBeats) - x;
    const y = trackRect.top;
    const height = trackRect.height;

    result.push({
      render: (ctx) => {
        ctx.beginPath();
        ctx.roundRect(x, y, width, height, CLIP_CORNER_RADIUS);
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.75)';
        ctx.stroke();
        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        ctx.fill();
      },
    });
  });

  if (dragState.targetInsertionSpec) {
    const trackId = dragState.targetInsertionSpec.trackId;
    const afterLastTrackElement =
      studioContext.timelineController.afterLastTrackRef.current;
    const trackElement = trackId
      ? studioContext.timelineController.trackHeadersRef.current[trackId]
      : null;

    if (!trackElement && !afterLastTrackElement) return result;

    const timelineRect = studioContext.timelineController.getWrapperRect();
    const afterLastTrackRect = afterLastTrackElement?.getBoundingClientRect();
    const trackRect = getCanvasRelativeRect(
      trackElement?.getBoundingClientRect() ||
        new DOMRect(
          afterLastTrackRect!.left,
          afterLastTrackRect!.top,
          afterLastTrackRect!.width,
          defaultStudioTrackHeight
        ),
      timelineRect
    );

    const x = studioContext.beatsToCanvasX(
      dragState.targetInsertionSpec.replacementStartBeats
    );
    const width =
      studioContext.beatsToCanvasX(
        dragState.targetInsertionSpec.replacementEndBeats
      ) - x;
    const y = trackRect.top;
    const height = trackRect.height;
    const readStartBeats =
      dragState.targetInsertionSpec.studioClip?.readStartBeats ?? 0;
    const replacementStartBeats =
      dragState.targetInsertionSpec.replacementStartBeats;

    result.push({
      render: (ctx) => {
        ctx.beginPath();
        ctx.roundRect(x, y, width, height, CLIP_CORNER_RADIUS);
        ctx.lineWidth = 1;
        ctx.strokeStyle = 'rgba(255, 255, 255, 1)';
        ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
        ctx.fill();
        ctx.stroke();

        if (readStartBeats < 0) {
          const readStartX = studioContext.beatsToCanvasX(
            replacementStartBeats - readStartBeats
          );
          ctx.beginPath();
          ctx.moveTo(readStartX, y);
          ctx.lineTo(readStartX, y + height);
          ctx.stroke();
        }
      },
    });
  }

  return result;
}
