/**
 * ExpandableChart - Wrapper component for charts that can be expanded to full-screen
 *
 * Features:
 * - Expand button to open chart in full-screen modal
 * - Interactive zoom and pan controls in expanded view
 * - Download as PNG/SVG
 * - Reset view button
 */

import React, { useState, useRef, useCallback } from 'react';
import { createPortal } from 'react-dom';

interface ExpandableChartProps {
  title: string;
  subtitle?: string;
  children: React.ReactNode;
  // Render function for the expanded version with larger dimensions
  renderExpanded?: (width: number, height: number) => React.ReactNode;
  className?: string;
}

export function ExpandableChart({
  title,
  subtitle,
  children,
  renderExpanded,
  className = ''
}: ExpandableChartProps) {
  const [isExpanded, setIsExpanded] = useState(false);
  const [zoom, setZoom] = useState(1);
  const [pan, setPan] = useState({ x: 0, y: 0 });
  const [isPanning, setIsPanning] = useState(false);
  const [panStart, setPanStart] = useState({ x: 0, y: 0 });
  const containerRef = useRef<HTMLDivElement>(null);
  const expandedContentRef = useRef<HTMLDivElement>(null);

  const handleExpand = () => {
    setIsExpanded(true);
    setZoom(1);
    setPan({ x: 0, y: 0 });
  };

  const handleClose = () => {
    setIsExpanded(false);
  };

  const handleZoomIn = () => {
    setZoom(prev => Math.min(prev * 1.25, 5));
  };

  const handleZoomOut = () => {
    setZoom(prev => Math.max(prev / 1.25, 0.25));
  };

  const handleResetView = () => {
    setZoom(1);
    setPan({ x: 0, y: 0 });
  };

  const handleWheel = useCallback((e: React.WheelEvent) => {
    e.preventDefault();
    const delta = e.deltaY > 0 ? 0.9 : 1.1;
    setZoom(prev => Math.min(Math.max(prev * delta, 0.25), 5));
  }, []);

  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    if (e.button === 0) { // Left click
      setIsPanning(true);
      setPanStart({ x: e.clientX - pan.x, y: e.clientY - pan.y });
    }
  }, [pan]);

  const handleMouseMove = useCallback((e: React.MouseEvent) => {
    if (isPanning) {
      setPan({
        x: e.clientX - panStart.x,
        y: e.clientY - panStart.y
      });
    }
  }, [isPanning, panStart]);

  const handleMouseUp = useCallback(() => {
    setIsPanning(false);
  }, []);

  const handleDownload = useCallback((format: 'png' | 'svg') => {
    const content = expandedContentRef.current;
    if (!content) return;

    const svg = content.querySelector('svg');
    if (!svg) {
      alert('No SVG found to download');
      return;
    }

    if (format === 'svg') {
      const svgData = new XMLSerializer().serializeToString(svg);
      const blob = new Blob([svgData], { type: 'image/svg+xml' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${title.replace(/\s+/g, '_')}.svg`;
      a.click();
      URL.revokeObjectURL(url);
    } else {
      // PNG export
      const svgData = new XMLSerializer().serializeToString(svg);
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const img = new Image();

      // Get actual SVG dimensions
      const svgWidth = svg.width.baseVal.value || 800;
      const svgHeight = svg.height.baseVal.value || 600;

      canvas.width = svgWidth * 2; // 2x for better quality
      canvas.height = svgHeight * 2;

      img.onload = () => {
        if (ctx) {
          ctx.fillStyle = 'white';
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

          const pngUrl = canvas.toDataURL('image/png');
          const a = document.createElement('a');
          a.href = pngUrl;
          a.download = `${title.replace(/\s+/g, '_')}.png`;
          a.click();
        }
      };

      img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData)));
    }
  }, [title]);

  // Calculate expanded dimensions
  const expandedWidth = typeof window !== 'undefined' ? window.innerWidth - 80 : 1200;
  const expandedHeight = typeof window !== 'undefined' ? window.innerHeight - 200 : 800;

  const modal = isExpanded ? createPortal(
    <div
      className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center"
      onClick={handleClose}
    >
      <div
        className="bg-white rounded-xl shadow-2xl max-w-[95vw] max-h-[95vh] overflow-hidden flex flex-col"
        onClick={e => e.stopPropagation()}
        style={{ width: expandedWidth + 40, height: expandedHeight + 160 }}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 bg-gray-50">
          <div>
            <h2 className="text-xl font-bold text-gray-900">{title}</h2>
            {subtitle && <p className="text-sm text-gray-500 mt-1">{subtitle}</p>}
          </div>

          <div className="flex items-center gap-2">
            {/* Zoom controls */}
            <div className="flex items-center gap-1 bg-gray-100 rounded-lg px-2 py-1">
              <button
                onClick={handleZoomOut}
                className="p-1.5 hover:bg-gray-200 rounded text-gray-700"
                title="Zoom out"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 12H4" />
                </svg>
              </button>
              <span className="text-sm font-medium text-gray-700 min-w-[3rem] text-center">
                {Math.round(zoom * 100)}%
              </span>
              <button
                onClick={handleZoomIn}
                className="p-1.5 hover:bg-gray-200 rounded text-gray-700"
                title="Zoom in"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
                </svg>
              </button>
            </div>

            {/* Reset button */}
            <button
              onClick={handleResetView}
              className="p-2 hover:bg-gray-200 rounded-lg text-gray-700"
              title="Reset view"
            >
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
              </svg>
            </button>

            {/* Download dropdown */}
            <div className="relative group">
              <button
                className="p-2 hover:bg-gray-200 rounded-lg text-gray-700"
                title="Download"
              >
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                </svg>
              </button>
              <div className="absolute right-0 top-full mt-1 bg-white rounded-lg shadow-lg border border-gray-200 py-1 hidden group-hover:block min-w-[120px]">
                <button
                  onClick={() => handleDownload('png')}
                  className="w-full px-4 py-2 text-left text-sm hover:bg-gray-100 text-gray-700"
                >
                  Download PNG
                </button>
                <button
                  onClick={() => handleDownload('svg')}
                  className="w-full px-4 py-2 text-left text-sm hover:bg-gray-100 text-gray-700"
                >
                  Download SVG
                </button>
              </div>
            </div>

            {/* Close button */}
            <button
              onClick={handleClose}
              className="p-2 hover:bg-red-100 rounded-lg text-gray-700 hover:text-red-600 ml-2"
              title="Close (Esc)"
            >
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
        </div>

        {/* Chart content with zoom/pan */}
        <div
          className="flex-1 overflow-hidden bg-white cursor-grab active:cursor-grabbing"
          onWheel={handleWheel}
          onMouseDown={handleMouseDown}
          onMouseMove={handleMouseMove}
          onMouseUp={handleMouseUp}
          onMouseLeave={handleMouseUp}
        >
          <div
            ref={expandedContentRef}
            className="w-full h-full flex items-center justify-center p-4"
            style={{
              transform: `scale(${zoom}) translate(${pan.x / zoom}px, ${pan.y / zoom}px)`,
              transformOrigin: 'center center',
              transition: isPanning ? 'none' : 'transform 0.1s ease-out'
            }}
          >
            {renderExpanded ? renderExpanded(expandedWidth, expandedHeight) : children}
          </div>
        </div>

        {/* Footer with instructions */}
        <div className="px-6 py-3 border-t border-gray-200 bg-gray-50 text-xs text-gray-500 flex items-center gap-4">
          <span>🖱️ Scroll to zoom</span>
          <span>✋ Drag to pan</span>
          <span>⌨️ Press Esc to close</span>
        </div>
      </div>
    </div>,
    document.body
  ) : null;

  // Handle Esc key
  React.useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isExpanded) {
        handleClose();
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isExpanded]);

  return (
    <div ref={containerRef} className={`relative ${className}`}>
      {/* Expand button */}
      <button
        onClick={handleExpand}
        className="absolute top-2 right-2 z-10 p-1.5 bg-white/90 hover:bg-white rounded-lg shadow-sm border border-gray-200 text-gray-600 hover:text-gray-900 transition-colors"
        title="Expand chart"
      >
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
        </svg>
      </button>

      {/* Original chart content */}
      {children}

      {/* Modal portal */}
      {modal}
    </div>
  );
}
