/**
 * ICTConceptsOverlay Component
 * Renders ICT concepts (Order Blocks, FVG, Liquidity) as highlighted zones on the chart
 * Uses area series with top/bottom lines to create box-like regions
 */

import { useEffect, useRef } from 'react';
import type { IChartApi, ISeriesApi, Time, LineData } from 'lightweight-charts';
import type { ICTConcept, ICTConceptType } from '../../../../../types/mlOverlay.types';

// ============================================================================
// Types
// ============================================================================

export interface ICTConceptsOverlayProps {
  chartRef: React.RefObject<IChartApi>;
  ictConcepts: ICTConcept[];
  visible?: boolean;
  colors?: Record<ICTConceptType, string>;
  showLabels?: boolean;
  onConceptClick?: (concept: ICTConcept) => void;
}

interface ConceptSeries {
  area: ISeriesApi<'Area'>;
  topLine: ISeriesApi<'Line'>;
  bottomLine: ISeriesApi<'Line'>;
}

// ============================================================================
// Default Colors
// ============================================================================

const DEFAULT_COLORS: Record<ICTConceptType, string> = {
  OrderBlock: 'rgba(59, 130, 246, 0.25)', // Blue
  FVG: 'rgba(251, 191, 36, 0.25)', // Yellow/Amber
  Liquidity: 'rgba(249, 115, 22, 0.25)', // Orange
};

const BORDER_COLORS: Record<ICTConceptType, string> = {
  OrderBlock: 'rgba(59, 130, 246, 0.6)',
  FVG: 'rgba(251, 191, 36, 0.6)',
  Liquidity: 'rgba(249, 115, 22, 0.6)',
};

// ============================================================================
// Helper Functions
// ============================================================================

function generateConceptId(concept: ICTConcept, index: number): string {
  return `ict-${concept.type}-${index}-${concept.timeStart}`;
}

function createLineData(
  timeStart: number,
  timeEnd: number,
  price: number
): LineData[] {
  return [
    { time: (timeStart / 1000) as Time, value: price },
    { time: (timeEnd / 1000) as Time, value: price },
  ];
}

function createAreaData(
  timeStart: number,
  timeEnd: number,
  priceTop: number
): LineData[] {
  // Area series uses the value as the top, and bottomColor fills below
  return [
    { time: (timeStart / 1000) as Time, value: priceTop },
    { time: (timeEnd / 1000) as Time, value: priceTop },
  ];
}

// ============================================================================
// Component
// ============================================================================

export const ICTConceptsOverlay: React.FC<ICTConceptsOverlayProps> = ({
  chartRef,
  ictConcepts,
  visible = true,
  colors = DEFAULT_COLORS,
  showLabels = true,
  onConceptClick,
}) => {
  const seriesMapRef = useRef<Map<string, ConceptSeries>>(new Map());

  // Initialize and update series for ICT concepts
  useEffect(() => {
    if (!chartRef.current) return;

    const chart = chartRef.current;

    // Clear existing series first
    seriesMapRef.current.forEach((conceptSeries) => {
      try {
        chart.removeSeries(conceptSeries.area);
        chart.removeSeries(conceptSeries.topLine);
        chart.removeSeries(conceptSeries.bottomLine);
      } catch {
        // Series might already be removed
      }
    });
    seriesMapRef.current.clear();

    if (!visible || ictConcepts.length === 0) return;

    // Create series for each concept
    ictConcepts.forEach((concept, index) => {
      const conceptId = generateConceptId(concept, index);
      const fillColor = colors[concept.type] || DEFAULT_COLORS[concept.type];
      const borderColor = BORDER_COLORS[concept.type];

      // Create area series for the zone fill
      const areaSeries = chart.addAreaSeries({
        topColor: fillColor,
        bottomColor: fillColor,
        lineColor: 'transparent',
        lineWidth: 1,
        crosshairMarkerVisible: false,
        lastValueVisible: false,
        priceLineVisible: false,
        priceScaleId: 'right',
      });

      // Create top boundary line
      const topLine = chart.addLineSeries({
        color: borderColor,
        lineWidth: 1,
        lineStyle: 0,
        crosshairMarkerVisible: false,
        lastValueVisible: showLabels,
        priceLineVisible: false,
        title: showLabels ? concept.type : '',
        priceScaleId: 'right',
      });

      // Create bottom boundary line
      const bottomLine = chart.addLineSeries({
        color: borderColor,
        lineWidth: 1,
        lineStyle: 0,
        crosshairMarkerVisible: false,
        lastValueVisible: false,
        priceLineVisible: false,
        priceScaleId: 'right',
      });

      // Set data for each series
      const areaData = createAreaData(
        concept.timeStart,
        concept.timeEnd,
        concept.priceTop
      );
      areaSeries.setData(areaData);

      const topLineData = createLineData(
        concept.timeStart,
        concept.timeEnd,
        concept.priceTop
      );
      topLine.setData(topLineData);

      const bottomLineData = createLineData(
        concept.timeStart,
        concept.timeEnd,
        concept.priceBottom
      );
      bottomLine.setData(bottomLineData);

      // Store series references
      seriesMapRef.current.set(conceptId, {
        area: areaSeries,
        topLine,
        bottomLine,
      });
    });

    return () => {
      // Cleanup on unmount
      seriesMapRef.current.forEach((conceptSeries) => {
        try {
          chart.removeSeries(conceptSeries.area);
          chart.removeSeries(conceptSeries.topLine);
          chart.removeSeries(conceptSeries.bottomLine);
        } catch {
          // Series might already be removed
        }
      });
      seriesMapRef.current.clear();
    };
  }, [chartRef, ictConcepts, visible, colors, showLabels]);

  // Handle click events for concepts
  useEffect(() => {
    if (!chartRef.current || !onConceptClick || ictConcepts.length === 0) return;

    const chart = chartRef.current;

    const handleClick = (param: { time?: Time; point?: { x: number; y: number } }) => {
      if (!param.time || !param.point) return;

      const clickedTime = (param.time as number) * 1000;

      // Find the concept that contains the clicked time
      const clickedConcept = ictConcepts.find(
        (concept) =>
          clickedTime >= concept.timeStart && clickedTime <= concept.timeEnd
      );

      if (clickedConcept) {
        onConceptClick(clickedConcept);
      }
    };

    chart.subscribeClick(handleClick);

    return () => {
      chart.unsubscribeClick(handleClick);
    };
  }, [chartRef, ictConcepts, onConceptClick]);

  // Update visibility
  useEffect(() => {
    seriesMapRef.current.forEach((conceptSeries) => {
      conceptSeries.area.applyOptions({ visible });
      conceptSeries.topLine.applyOptions({ visible });
      conceptSeries.bottomLine.applyOptions({ visible });
    });
  }, [visible]);

  return null;
};

export default ICTConceptsOverlay;
