'use client';

import { useMemo } from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import type { PhysicalSales, StreamData } from '../types/schemas';
import type { Event } from '../utils/transformCampaigns';

// Parse date from MM/DD/YY format to timestamp
const parseDateToTimestamp = (dateStr: string): number => {
    const [month, day, year] = dateStr.split('/').map(num => parseInt(num, 10));
    // Year is 2-digit, so convert to 4-digit (assuming 20XX)
    const fullYear = 2000 + year;
    return new Date(fullYear, month - 1, day).getTime();
};

// Map icon to color for markers
const getMarkerColor = (icon: string) => {
    const colorMap: { [key: string]: string } = {
        '💰': '#10B981', // green for sales
        '🌐': '#3B82F6', // blue for traffic
        '👁️': '#8B5CF6', // purple for awareness
        '📱': '#3B82F6', // blue for meta
        '📧': '#F97316', // orange for email
        '📰': '#EF4444', // red for news
        '🎵': '#EC4899', // pink for releases
        '📊': '#6B7280', // gray for generic
    };
    return colorMap[icon] || '#6B7280';
};

interface StreamsChartProps {
    events: Event[];
    streamsData: StreamData[];
    physicalSalesData?: PhysicalSales[];
    chartMode: 'streams' | 'physical';
    physicalMetric: 'dollars' | 'units';
    hasPhysicalSales: boolean;
    timeRange: '1 Year' | '6 Months' | '28 Days';
    onTimeRangeChange: (range: '1 Year' | '6 Months' | '28 Days') => void;
    onChartModeChange: (mode: 'streams' | 'physical') => void;
    onPhysicalMetricChange: (metric: 'dollars' | 'units') => void;
    onMarkerHover?: (dateTimestamp: number | null) => void;
}

export default function StreamsChart({
    events,
    streamsData,
    physicalSalesData,
    chartMode,
    physicalMetric,
    hasPhysicalSales,
    timeRange,
    onTimeRangeChange,
    onChartModeChange,
    onPhysicalMetricChange,
    onMarkerHover,
}: StreamsChartProps) {
    // Convert streams data to chart format - using only All Streams
    const chartData = useMemo(() => {
        if (!streamsData || streamsData.length === 0) {
            return [];
        }

        return streamsData
            .map(stream => {
                const timestamp = parseDateToTimestamp(stream.date);
                const value = stream.allStreams;
                return [timestamp, value];
            })
            .sort((a, b) => a[0] - b[0]); // Sort by date
    }, [streamsData]);

    // Convert physical sales data to chart format for bar chart
    const physicalSalesChartData = useMemo(() => {
        if (!physicalSalesData || physicalSalesData.length === 0) {
            return { units: [], dollars: [] };
        }

        const unitsData = physicalSalesData
            .map(sale => {
                const timestamp = new Date(sale.date).getTime();
                return [timestamp, sale.units];
            })
            .sort((a, b) => a[0] - b[0]);

        const dollarsData = physicalSalesData
            .map(sale => {
                const timestamp = new Date(sale.date).getTime();
                return [timestamp, sale.dollars];
            })
            .sort((a, b) => a[0] - b[0]);

        return { units: unitsData, dollars: dollarsData };
    }, [physicalSalesData]);

    // Create plot lines for events - group by date to handle overlapping markers
    const plotLines = useMemo(() => {
        // Group events by date
        const eventsByDate = events.reduce(
            (acc, event) => {
                const dateKey = event.dateTimestamp;
                if (!acc[dateKey]) {
                    acc[dateKey] = [];
                }
                acc[dateKey].push(event);
                return acc;
            },
            {} as Record<number, typeof events>
        );

        // Create plot lines - one per unique date with stacked icons
        return Object.entries(eventsByDate).map(([timestamp, dateEvents]) => {
            const icons = dateEvents.map(e => e.icon).join(' ');
            const colors = dateEvents.map(e => getMarkerColor(e.icon));
            // Use the first color or blend if multiple
            const color = colors[0];

            return {
                color: color,
                width: 2,
                value: Number(timestamp),
                dashStyle: 'Solid' as Highcharts.DashStyleValue,
                zIndex: 5,
                label: {
                    text: icons,
                    align: 'center' as const,
                    verticalAlign: 'top' as const,
                    rotation: 0,
                    style: {
                        fontSize: '18px',
                        background: 'white',
                        padding: '2px 4px',
                        borderRadius: 4,
                    },
                    y: -10,
                },
            };
        });
    }, [events]);

    // Create interactive marker points for hover functionality
    const markerPoints = useMemo(() => {
        // Group events by date
        const eventsByDate = events.reduce(
            (acc, event) => {
                const dateKey = event.dateTimestamp;
                if (!acc[dateKey]) {
                    acc[dateKey] = [];
                }
                acc[dateKey].push(event);
                return acc;
            },
            {} as Record<number, typeof events>
        );

        // Find the max value for positioning markers at the top
        let maxValue = 0;
        if (chartMode === 'streams') {
            maxValue =
                chartData.length > 0
                    ? Math.max(...chartData.map(d => d[1]))
                    : 0;
        } else {
            // For physical sales, use the max from the selected metric
            const selectedData =
                physicalMetric === 'dollars'
                    ? physicalSalesChartData.dollars
                    : physicalSalesChartData.units;
            maxValue =
                selectedData.length > 0
                    ? Math.max(...selectedData.map(d => d[1]))
                    : 0;
        }

        // Create scatter points at each event date
        return Object.entries(eventsByDate).map(([timestamp, dateEvents]) => {
            const icons = dateEvents.map(e => e.icon).join(' ');
            return {
                x: Number(timestamp),
                y: maxValue * 1.05, // Position slightly above the chart
                timestamp: Number(timestamp),
                icons: icons,
                events: dateEvents,
            };
        });
    }, [events, chartData, chartMode, physicalMetric, physicalSalesChartData]);

    const options: Highcharts.Options =
        chartMode === 'streams'
            ? {
                  // STREAMS MODE - Area Chart
                  chart: {
                      type: 'area',
                      height: 550,
                      backgroundColor: 'transparent',
                      style: {
                          fontFamily: 'Inter, sans-serif',
                      },
                      spacingTop: 30,
                      zooming: {
                          type: 'x',
                          resetButton: {
                              position: {
                                  align: 'right',
                                  verticalAlign: 'top',
                                  x: -10,
                                  y: 10,
                              },
                              theme: {
                                  fill: '#8B5CF6',
                                  stroke: '#8B5CF6',
                                  style: {
                                      color: '#FFFFFF',
                                      fontWeight: '600',
                                  },
                                  r: 6,
                                  states: {
                                      hover: {
                                          fill: '#7C3AED',
                                          style: {
                                              color: '#FFFFFF',
                                          },
                                      },
                                  },
                              },
                          },
                      },
                      panning: {
                          enabled: true,
                          type: 'x',
                      },
                      panKey: 'shift',
                  },
                  title: {
                      text: undefined,
                  },
                  credits: {
                      enabled: false,
                  },
                  xAxis: {
                      type: 'datetime',
                      labels: {
                          format: '{value:%b %e}',
                          style: {
                              color: '#6B7280',
                              fontSize: '12px',
                          },
                      },
                      lineColor: '#E5E7EB',
                      tickColor: '#E5E7EB',
                      plotLines: plotLines,
                  },
                  yAxis: {
                      title: {
                          text: undefined,
                      },
                      labels: {
                          formatter: function () {
                              const val = this.value as number;
                              if (val >= 1000000) {
                                  return (val / 1000000).toFixed(1) + 'M';
                              }
                              return val.toString();
                          },
                          style: {
                              color: '#6B7280',
                              fontSize: '12px',
                          },
                      },
                      gridLineColor: '#F3F4F6',
                  },
                  tooltip: {
                      shared: true,
                      backgroundColor: '#FFFFFF',
                      borderColor: '#E5E7EB',
                      borderRadius: 8,
                      shadow: false,
                      useHTML: true,
                      formatter: function () {
                          const date = new Date(this.x as number);
                          const value = (this.y as number).toLocaleString();
                          return `
          <div style="padding: 8px;">
            <div style="font-size: 12px; color: #6B7280; margin-bottom: 4px;">
              ${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
            </div>
            <div style="font-size: 14px; font-weight: 600; color: #111827;">
              ${value} streams
            </div>
          </div>
        `;
                      },
                  },
                  plotOptions: {
                      area: {
                          fillColor: {
                              linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                              stops: [
                                  [0, 'rgba(139, 92, 246, 0.8)'],
                                  [1, 'rgba(139, 92, 246, 0.1)'],
                              ],
                          },
                          lineWidth: 2,
                          lineColor: '#8B5CF6',
                          marker: {
                              enabled: false,
                              states: {
                                  hover: {
                                      enabled: true,
                                      radius: 4,
                                  },
                              },
                          },
                          states: {
                              hover: {
                                  lineWidth: 2,
                              },
                          },
                      },
                  },
                  series: [
                      {
                          type: 'area',
                          name: 'Streams',
                          data: chartData,
                      },
                      {
                          type: 'scatter',
                          name: 'Events',
                          data: markerPoints.map(point => ({
                              x: point.x,
                              y: point.y,
                              timestamp: point.timestamp,
                          })),
                          marker: {
                              enabled: true,
                              radius: 20,
                              symbol: 'circle',
                              fillColor: 'rgba(0, 0, 0, 0)',
                              lineWidth: 0,
                              states: {
                                  hover: {
                                      enabled: true,
                                      fillColor: 'rgba(139, 92, 246, 0.1)',
                                      lineWidth: 2,
                                      lineColor: '#8B5CF6',
                                      radius: 22,
                                  },
                              },
                          },
                          enableMouseTracking: true,
                          showInLegend: false,
                          states: {
                              hover: {
                                  enabled: true,
                              },
                              inactive: {
                                  opacity: 1,
                              },
                          },
                          point: {
                              events: {
                                  mouseOver: function () {
                                      const point = this as any;
                                      if (onMarkerHover) {
                                          onMarkerHover(point.timestamp);
                                      }
                                  },
                                  mouseOut: function () {
                                      if (onMarkerHover) {
                                          onMarkerHover(null);
                                      }
                                  },
                              },
                          },
                      },
                  ],
                  legend: {
                      enabled: false,
                  },
              }
            : {
                  // PHYSICAL SALES MODE - Area Chart with Single Series
                  chart: {
                      type: 'area',
                      height: 550,
                      backgroundColor: 'transparent',
                      style: {
                          fontFamily: 'Inter, sans-serif',
                      },
                      spacingTop: 30,
                      zooming: {
                          type: 'x',
                          resetButton: {
                              position: {
                                  align: 'right',
                                  verticalAlign: 'top',
                                  x: -10,
                                  y: 10,
                              },
                              theme: {
                                  fill: '#8B5CF6',
                                  stroke: '#8B5CF6',
                                  style: {
                                      color: '#FFFFFF',
                                      fontWeight: '600',
                                  },
                                  r: 6,
                                  states: {
                                      hover: {
                                          fill: '#7C3AED',
                                          style: {
                                              color: '#FFFFFF',
                                          },
                                      },
                                  },
                              },
                          },
                      },
                      panning: {
                          enabled: true,
                          type: 'x',
                      },
                      panKey: 'shift',
                  },
                  title: {
                      text: undefined,
                  },
                  credits: {
                      enabled: false,
                  },
                  xAxis: {
                      type: 'datetime',
                      labels: {
                          format: '{value:%b %e}',
                          style: {
                              color: '#6B7280',
                              fontSize: '12px',
                          },
                      },
                      lineColor: '#E5E7EB',
                      tickColor: '#E5E7EB',
                      plotLines: plotLines,
                  },
                  yAxis: {
                      title: {
                          text: undefined,
                      },
                      labels: {
                          formatter: function () {
                              const val = this.value as number;
                              if (physicalMetric === 'dollars') {
                                  return '$' + val.toLocaleString();
                              }
                              return val.toLocaleString();
                          },
                          style: {
                              color: '#6B7280',
                              fontSize: '12px',
                          },
                      },
                      gridLineColor: '#F3F4F6',
                  },
                  tooltip: {
                      shared: true,
                      backgroundColor: '#FFFFFF',
                      borderColor: '#E5E7EB',
                      borderRadius: 8,
                      shadow: false,
                      useHTML: true,
                      formatter: function () {
                          const date = new Date(this.x as number);
                          const value =
                              physicalMetric === 'dollars'
                                  ? '$' +
                                    (this.y as number).toLocaleString('en-US', {
                                        minimumFractionDigits: 2,
                                        maximumFractionDigits: 2,
                                    })
                                  : (this.y as number).toLocaleString();
                          return `
          <div style="padding: 8px;">
            <div style="font-size: 12px; color: #6B7280; margin-bottom: 4px;">
              ${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
            </div>
            <div style="font-size: 14px; font-weight: 600; color: #111827;">
              ${value} ${physicalMetric === 'dollars' ? '' : 'units'}
            </div>
          </div>
        `;
                      },
                  },
                  plotOptions: {
                      area: {
                          fillColor: {
                              linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                              stops:
                                  physicalMetric === 'dollars'
                                      ? [
                                            [0, 'rgba(139, 92, 246, 0.8)'],
                                            [1, 'rgba(139, 92, 246, 0.1)'],
                                        ]
                                      : [
                                            [0, 'rgba(167, 139, 250, 0.8)'],
                                            [1, 'rgba(167, 139, 250, 0.1)'],
                                        ],
                          },
                          lineWidth: 2,
                          lineColor:
                              physicalMetric === 'dollars'
                                  ? '#8B5CF6'
                                  : '#A78BFA',
                          marker: {
                              enabled: false,
                              states: {
                                  hover: {
                                      enabled: true,
                                      radius: 4,
                                  },
                              },
                          },
                          states: {
                              hover: {
                                  lineWidth: 2,
                              },
                          },
                      },
                  },
                  series: [
                      {
                          type: 'area',
                          name:
                              physicalMetric === 'dollars' ? 'Dollars' : 'Units',
                          data:
                              physicalMetric === 'dollars'
                                  ? physicalSalesChartData.dollars
                                  : physicalSalesChartData.units,
                      },
                      {
                          type: 'scatter',
                          name: 'Events',
                          data: markerPoints.map(point => ({
                              x: point.x,
                              y: point.y,
                              timestamp: point.timestamp,
                          })),
                          marker: {
                              enabled: true,
                              radius: 20,
                              symbol: 'circle',
                              fillColor: 'rgba(0, 0, 0, 0)',
                              lineWidth: 0,
                              states: {
                                  hover: {
                                      enabled: true,
                                      fillColor: 'rgba(139, 92, 246, 0.1)',
                                      lineWidth: 2,
                                      lineColor: '#8B5CF6',
                                      radius: 22,
                                  },
                              },
                          },
                          enableMouseTracking: true,
                          showInLegend: false,
                          states: {
                              hover: {
                                  enabled: true,
                              },
                              inactive: {
                                  opacity: 1,
                              },
                          },
                          point: {
                              events: {
                                  mouseOver: function () {
                                      const point = this as any;
                                      if (onMarkerHover) {
                                          onMarkerHover(point.timestamp);
                                      }
                                  },
                                  mouseOut: function () {
                                      if (onMarkerHover) {
                                          onMarkerHover(null);
                                      }
                                  },
                              },
                          },
                      },
                  ],
                  legend: {
                      enabled: false,
                  },
              };

    return (
        <div className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100  h-[650px]">
            {/* Header with Chart Mode Dropdown, Market Label and Time Filters */}
            <div className="flex items-center justify-between mb-6">
                {/* Left side - Dropdown and Market Label */}
                <div className="flex items-center gap-3">
                    {/* Chart Mode Dropdown */}
                    <select
                        value={chartMode}
                        onChange={e =>
                            onChartModeChange(
                                e.target.value as 'streams' | 'physical'
                            )
                        }
                        className="px-3 py-1.5 rounded-lg text-sm font-medium border border-gray-200 bg-white text-gray-700 hover:border-purple-300 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-colors"
                    >
                        <option value="streams">All Streams</option>
                        <option value="physical" disabled={!hasPhysicalSales}>
                            Physical Sales
                        </option>
                    </select>

                    {/* Physical Sales Metric Dropdown - Only show when in physical mode */}
                    {chartMode === 'physical' && (
                        <select
                            value={physicalMetric}
                            onChange={e =>
                                onPhysicalMetricChange(
                                    e.target.value as 'dollars' | 'units'
                                )
                            }
                            className="px-3 py-1.5 rounded-lg text-sm font-medium border border-gray-200 bg-white text-gray-700 hover:border-purple-300 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-colors"
                        >
                            <option value="dollars">Dollars</option>
                            <option value="units">Units</option>
                        </select>
                    )}

                    {/* Market Label - Only show for streams */}
                    {/*{chartMode === 'streams' && (*/}
                    {/*    <div className="text-sm font-medium text-gray-700">*/}
                    {/*        in the US market*/}
                    {/*    </div>*/}
                    {/*)}*/}
                </div>

                {/* Time Period Filters */}
                <div className="flex items-center gap-2 bg-gray-100 rounded-lg p-1">
                    {(['1 Year', '6 Months', '28 Days'] as const).map(p => (
                        <button
                            key={p}
                            onClick={() => onTimeRangeChange(p)}
                            className={`px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${
                                timeRange === p
                                    ? 'bg-purple-500 text-white shadow-sm'
                                    : 'text-gray-600 hover:text-gray-900'
                            }`}
                        >
                            {p}
                        </button>
                    ))}
                </div>
            </div>

            {/* Chart */}
            <HighchartsReact highcharts={Highcharts} options={options} />
        </div>
    );
}
