import { useState, useEffect, useCallback } from 'react';
import type { Segment, SegmentMetrics } from './types';

export interface SegmentComparisonProps {
  /** Segments to compare */
  segments: Segment[];
  /** Date range start */
  startDate: string;
  /** Date range end */
  endDate: string;
  /** Base URL for segments API (default: /api/segments) */
  apiBaseUrl?: string;
  /** Metric to highlight as winner */
  primaryMetric?: keyof SegmentMetrics;
  /** Custom CSS class */
  className?: string;
}

/** Format number with appropriate suffix */
const formatNumber = (value: number): string => {
  if (value >= 1000000) {
    return `${(value / 1000000).toFixed(1)}M`;
  }
  if (value >= 1000) {
    return `${(value / 1000).toFixed(1)}K`;
  }
  return value.toLocaleString();
};

/** Format percentage */
const formatPercent = (value: number): string => {
  return `${(value * 100).toFixed(1)}%`;
};

/** Format duration in seconds to human readable */
const formatDuration = (seconds: number): string => {
  if (seconds < 60) {
    return `${Math.round(seconds)}s`;
  }
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = Math.round(seconds % 60);
  return `${minutes}m ${remainingSeconds}s`;
};

/** Metric display configuration */
const METRIC_CONFIG: Record<
  keyof SegmentMetrics,
  { label: string; format: (v: number) => string; higherIsBetter: boolean }
> = {
  segmentId: { label: 'ID', format: String, higherIsBetter: true },
  segmentName: { label: 'Name', format: String, higherIsBetter: true },
  sessions: { label: 'Sessions', format: formatNumber, higherIsBetter: true },
  users: { label: 'Users', format: formatNumber, higherIsBetter: true },
  engagementRate: { label: 'Engagement Rate', format: formatPercent, higherIsBetter: true },
  conversionRate: { label: 'Conversion Rate', format: formatPercent, higherIsBetter: true },
  avgSessionDuration: { label: 'Avg. Duration', format: formatDuration, higherIsBetter: true },
  pagesPerSession: { label: 'Pages/Session', format: (v) => v.toFixed(1), higherIsBetter: true },
  revenue: { label: 'Revenue', format: (v) => `$${formatNumber(v)}`, higherIsBetter: true },
};

/** Metrics to display in comparison table */
const DISPLAY_METRICS: (keyof SegmentMetrics)[] = [
  'sessions',
  'users',
  'engagementRate',
  'conversionRate',
  'avgSessionDuration',
  'pagesPerSession',
  'revenue',
];

/**
 * Table comparing metrics across multiple segments
 */
export function SegmentComparison({
  segments,
  startDate,
  endDate,
  apiBaseUrl = '/api/segments',
  primaryMetric = 'sessions',
  className,
}: SegmentComparisonProps) {
  const [metricsData, setMetricsData] = useState<SegmentMetrics[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchSegmentMetrics = useCallback(async () => {
    if (segments.length === 0) {
      setMetricsData([]);
      setLoading(false);
      return;
    }

    setLoading(true);
    setError(null);

    try {
      const promises = segments.map(async (segment) => {
        const params = new URLSearchParams({ startDate, endDate });
        const response = await fetch(`${apiBaseUrl}/${segment.id}/apply?${params}`);
        if (!response.ok) {
          throw new Error(`Failed to fetch metrics for ${segment.name}`);
        }
        return response.json() as Promise<SegmentMetrics>;
      });

      const results = await Promise.all(promises);
      setMetricsData(results);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load segment comparison');
    } finally {
      setLoading(false);
    }
  }, [segments, startDate, endDate, apiBaseUrl]);

  useEffect(() => {
    fetchSegmentMetrics();
  }, [fetchSegmentMetrics]);

  const getWinner = (metric: keyof SegmentMetrics): string | null => {
    if (metricsData.length < 2) return null;

    const config = METRIC_CONFIG[metric];
    const values = metricsData.map((m) => ({ id: m.segmentId, value: m[metric] as number }));

    if (config.higherIsBetter) {
      const max = values.reduce((a, b) => (a.value > b.value ? a : b));
      return max.id;
    } else {
      const min = values.reduce((a, b) => (a.value < b.value ? a : b));
      return min.id;
    }
  };

  const calculateDelta = (
    baseValue: number,
    compareValue: number
  ): { value: number; isPositive: boolean } => {
    if (baseValue === 0) return { value: 0, isPositive: true };
    const delta = ((compareValue - baseValue) / baseValue) * 100;
    return { value: Math.abs(delta), isPositive: delta >= 0 };
  };

  if (segments.length === 0) {
    return (
      <div
        className={className}
        style={{
          padding: '40px',
          textAlign: 'center',
          color: '#666',
          backgroundColor: '#f9f9f9',
          borderRadius: '8px',
        }}
      >
        Select at least one segment to compare
      </div>
    );
  }

  if (loading) {
    return (
      <div
        className={className}
        style={{
          padding: '40px',
          textAlign: 'center',
          color: '#666',
        }}
      >
        Loading comparison data...
      </div>
    );
  }

  if (error) {
    return (
      <div
        className={className}
        style={{
          padding: '20px',
          backgroundColor: '#ffebee',
          color: '#c62828',
          borderRadius: '8px',
        }}
      >
        {error}
      </div>
    );
  }

  return (
    <div
      className={className}
      style={{
        overflowX: 'auto',
      }}
    >
      <table
        style={{
          width: '100%',
          borderCollapse: 'collapse',
          fontSize: '14px',
        }}
      >
        <thead>
          <tr>
            <th
              style={{
                padding: '12px 16px',
                textAlign: 'left',
                borderBottom: '2px solid #e0e0e0',
                backgroundColor: '#fafafa',
                fontWeight: 600,
              }}
            >
              Metric
            </th>
            {metricsData.map((data) => (
              <th
                key={data.segmentId}
                style={{
                  padding: '12px 16px',
                  textAlign: 'right',
                  borderBottom: '2px solid #e0e0e0',
                  backgroundColor: '#fafafa',
                  fontWeight: 600,
                  minWidth: '120px',
                }}
              >
                {data.segmentName}
              </th>
            ))}
            {metricsData.length === 2 && (
              <th
                style={{
                  padding: '12px 16px',
                  textAlign: 'right',
                  borderBottom: '2px solid #e0e0e0',
                  backgroundColor: '#fafafa',
                  fontWeight: 600,
                  minWidth: '100px',
                }}
              >
                Delta
              </th>
            )}
          </tr>
        </thead>
        <tbody>
          {DISPLAY_METRICS.map((metric) => {
            const config = METRIC_CONFIG[metric];
            const winnerId = getWinner(metric);
            const isPrimaryMetric = metric === primaryMetric;

            return (
              <tr
                key={metric}
                style={{
                  backgroundColor: isPrimaryMetric ? '#f0f7ff' : 'transparent',
                }}
              >
                <td
                  style={{
                    padding: '12px 16px',
                    borderBottom: '1px solid #e0e0e0',
                    fontWeight: isPrimaryMetric ? 600 : 400,
                  }}
                >
                  {config.label}
                  {isPrimaryMetric && (
                    <span
                      style={{
                        marginLeft: '8px',
                        fontSize: '10px',
                        padding: '2px 6px',
                        backgroundColor: '#1976d2',
                        color: '#fff',
                        borderRadius: '4px',
                        textTransform: 'uppercase',
                      }}
                    >
                      Primary
                    </span>
                  )}
                </td>
                {metricsData.map((data) => {
                  const value = data[metric] as number;
                  const isWinner = winnerId === data.segmentId && metricsData.length > 1;

                  return (
                    <td
                      key={data.segmentId}
                      style={{
                        padding: '12px 16px',
                        textAlign: 'right',
                        borderBottom: '1px solid #e0e0e0',
                        fontWeight: isWinner ? 600 : 400,
                        color: isWinner ? '#2e7d32' : 'inherit',
                      }}
                    >
                      {config.format(value)}
                      {isWinner && <span style={{ marginLeft: '4px', fontSize: '12px' }}>✓</span>}
                    </td>
                  );
                })}
                {metricsData.length === 2 && (
                  <td
                    style={{
                      padding: '12px 16px',
                      textAlign: 'right',
                      borderBottom: '1px solid #e0e0e0',
                    }}
                  >
                    {(() => {
                      const delta = calculateDelta(
                        metricsData[0][metric] as number,
                        metricsData[1][metric] as number
                      );
                      const isGood = config.higherIsBetter ? delta.isPositive : !delta.isPositive;
                      return (
                        <span
                          style={{
                            color: isGood ? '#2e7d32' : '#c62828',
                            fontWeight: 500,
                          }}
                        >
                          {delta.isPositive ? '+' : '-'}
                          {delta.value.toFixed(1)}%
                        </span>
                      );
                    })()}
                  </td>
                )}
              </tr>
            );
          })}
        </tbody>
      </table>

      {/* Summary */}
      {metricsData.length >= 2 && (
        <div
          style={{
            marginTop: '16px',
            padding: '12px 16px',
            backgroundColor: '#e8f5e9',
            borderRadius: '6px',
            fontSize: '13px',
          }}
        >
          <strong>Winner by {METRIC_CONFIG[primaryMetric].label}:</strong>{' '}
          {metricsData.find((m) => m.segmentId === getWinner(primaryMetric))?.segmentName || 'N/A'}
        </div>
      )}
    </div>
  );
}
