import React, { useState, useRef, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { createPortal } from 'react-dom';
import { X, GripHorizontal, Maximize2, Minimize2 } from 'lucide-react';
import { Button } from '../ui/button';
import { cn } from '../shared/utils';

interface FloatingMediaWrapperProps {
  children: React.ReactNode;
  isFloating: boolean;
  setIsFloating: (floating: boolean) => void;
  title?: string;
  onClose?: () => void;
  onCloseMedia?: () => void;
  aspectRatio?: number;
  className?: string;
  minWidth?: number;
  minHeight?: number;
  colorVariant?: 'default' | 'primary';
  playerId?: string;
  enablePadding?: boolean;
}

export function FloatingMediaWrapper({
  children,
  isFloating,
  setIsFloating,
  title,
  onClose,
  onCloseMedia,
  aspectRatio = 16 / 9,
  className,
  minWidth = 320,
  minHeight = 110,
  colorVariant = 'default',
  playerId = 'default',
  enablePadding = false,
}: FloatingMediaWrapperProps) {
  const { t } = useTranslation();
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
    return () => setIsMounted(false);
  }, []);

  // Placeholder when content is floating
  if (isFloating) {
    return (
      <>
        <div
          className={cn(
            'w-full rounded-[var(--radius-card)] bg-muted/20 border border-dashed border-muted-foreground/20 flex items-center justify-center flex-col gap-2 p-8 text-muted-foreground transition-all',
            className
          )}
          style={{ aspectRatio }}
        >
          <Maximize2 className="w-8 h-8 opacity-50" />
          <p className="text-sm font-medium">{t('media.playingFloating')}</p>
          <Button variant="outline" size="sm" onClick={() => setIsFloating(false)}>
            {t('media.restoreToPage')}
          </Button>
        </div>
        {isMounted &&
          createPortal(
            <FloatingContainer
              setIsFloating={setIsFloating}
              onClose={onClose}
              onCloseMedia={onCloseMedia}
              title={title}
              aspectRatio={aspectRatio}
              minWidth={minWidth}
              minHeight={minHeight}
              colorVariant={colorVariant}
              playerId={playerId}
              enablePadding={enablePadding}
            >
              {children}
            </FloatingContainer>,
            document.body
          )}
      </>
    );
  }

  return (
    <div className={cn('relative w-full overflow-hidden rounded-[var(--radius-card)]', className)}>
      {children}
    </div>
  );
}

interface FloatingContainerProps {
  children: React.ReactNode;
  setIsFloating: (floating: boolean) => void;
  onClose?: () => void;
  onCloseMedia?: () => void;
  title?: string;
  aspectRatio: number;
  minWidth: number;
  minHeight: number;
  colorVariant: 'default' | 'primary';
  playerId?: string;
  enablePadding?: boolean;
}

function FloatingContainer({
  children,
  setIsFloating,
  onClose,
  onCloseMedia,
  title,
  aspectRatio,
  minWidth,
  minHeight,
  colorVariant,
  playerId = 'default',
  enablePadding = false,
}: FloatingContainerProps) {
  const { t } = useTranslation();
  const minPlayerHeight = minWidth / aspectRatio;
  const containerRef = useRef<HTMLDivElement>(null);
  const resizeHandleRef = useRef<string | null>(null);

  const getInitialState = useCallback(() => {
    const storageKey = `xertica-media-player-${playerId}`;
    const stored = typeof window !== 'undefined' ? window.localStorage?.getItem(storageKey) : null;
    if (stored) {
      try {
        return JSON.parse(stored);
      } catch {
        // invalid stored data
      }
    }
    return {
      position: {
        x: typeof window !== 'undefined' ? window.innerWidth - minWidth - 24 : 0,
        y: typeof window !== 'undefined' ? window.innerHeight - minPlayerHeight - 24 : 0,
      },
      size: {
        width: minWidth,
        height: minPlayerHeight,
      },
    };
  }, [minWidth, minPlayerHeight, playerId]);

  interface FloatingState {
    position: { x: number; y: number };
    size: { width: number; height: number };
  }

  const [state, setState] = useState<FloatingState>(getInitialState);
  const { position, size } = state;
  const [isDragging, setIsDragging] = useState(false);
  const [isResizing, setIsResizing] = useState(false);
  const dragStartPos = useRef({ x: 0, y: 0 });
  const dragStartOffset = useRef({ x: 0, y: 0 });
  const resizeStartState = useRef({ position: { x: 0, y: 0 }, size: { width: 0, height: 0 } });

  const saveState = useCallback(
    (newPosition: { x: number; y: number }, newSize: { width: number; height: number }) => {
      if (typeof window === 'undefined') return;
      const storageKey = `xertica-media-player-${playerId}`;
      window.localStorage?.setItem(
        storageKey,
        JSON.stringify({ position: newPosition, size: newSize })
      );
    },
    [playerId]
  );

  const handleMouseDown = (e: React.MouseEvent) => {
    setIsDragging(true);
    dragStartPos.current = { x: e.clientX, y: e.clientY };
    dragStartOffset.current = { x: position.x, y: position.y };
  };

  const handleResizeStart = (e: React.MouseEvent, direction: string) => {
    e.stopPropagation();
    setIsResizing(true);
    resizeHandleRef.current = direction;
    dragStartPos.current = { x: e.clientX, y: e.clientY };
    resizeStartState.current = { position: { ...position }, size: { ...size } };
  };

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (isDragging) {
        const deltaX = e.clientX - dragStartPos.current.x;
        const deltaY = e.clientY - dragStartPos.current.y;
        const newPos = {
          x: dragStartOffset.current.x + deltaX,
          y: dragStartOffset.current.y + deltaY,
        };
        setState(prev => ({ ...prev, position: newPos }));
        saveState(newPos, state.size);
      }

      if (isResizing && resizeHandleRef.current) {
        const deltaX = e.clientX - dragStartPos.current.x;
        const deltaY = e.clientY - dragStartPos.current.y;
        const direction = resizeHandleRef.current;

        let newPos = { ...resizeStartState.current.position };
        let newSize = { ...resizeStartState.current.size };

        // Right resize - only increase width
        if (direction.includes('right')) {
          newSize.width = Math.max(minWidth, resizeStartState.current.size.width + deltaX);
        }
        // Left resize - adjust width and position
        if (direction.includes('left')) {
          const newW = Math.max(minWidth, resizeStartState.current.size.width - deltaX);
          newPos.x =
            resizeStartState.current.position.x + (resizeStartState.current.size.width - newW);
          newSize.width = newW;
        }
        // Bottom resize - only increase height
        if (direction.includes('bottom')) {
          newSize.height = Math.max(minHeight, resizeStartState.current.size.height + deltaY);
        }
        // Top resize - adjust height and position
        if (direction.includes('top')) {
          const newH = Math.max(minHeight, resizeStartState.current.size.height - deltaY);
          newPos.y =
            resizeStartState.current.position.y + (resizeStartState.current.size.height - newH);
          newSize.height = newH;
        }

        setState({ position: newPos, size: newSize });
        saveState(newPos, newSize);
      }
    },
    [isDragging, isResizing, state.size, minWidth, minHeight, saveState]
  );

  const handleMouseUp = useCallback(() => {
    setIsDragging(false);
    setIsResizing(false);
    resizeHandleRef.current = null;
  }, []);

  useEffect(() => {
    if (!isDragging && !isResizing) return;

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, isResizing, handleMouseMove, handleMouseUp]);

  return (
    <div className="fixed inset-0 pointer-events-none z-50 overflow-hidden">
      <div
        ref={containerRef}
        className="pointer-events-auto absolute"
        style={{
          transform: `translate(${position.x}px, ${position.y}px)`,
          width: size.width,
          height: size.height,
        }}
        role="dialog"
        aria-label={title || t('media.playingMedia')}
      >
        <div
          className={cn(
            'shadow-2xl rounded-[var(--radius-card)] overflow-hidden border backdrop-blur-sm',
            colorVariant === 'primary'
              ? 'bg-primary border-primary-foreground/20 text-primary-foreground'
              : 'border-border bg-card/95 text-card-foreground'
          )}
        >
          <div className="flex flex-col h-full w-full">
            <div
              className={cn(
                'h-9 backdrop-blur-sm border-b flex items-center justify-between px-2 cursor-move select-none',
                colorVariant === 'primary'
                  ? 'bg-primary-foreground/10 border-primary-foreground/10'
                  : 'bg-muted/20 border-border/40'
              )}
              onMouseDown={handleMouseDown}
              style={{ touchAction: 'none', userSelect: 'none' }}
            >
              <div
                className={cn(
                  'flex items-center gap-2 text-[10px] uppercase tracking-wider font-bold truncate flex-1',
                  colorVariant === 'primary' ? 'text-primary-foreground' : 'text-muted-foreground'
                )}
              >
                <GripHorizontal className="w-3.5 h-3.5" />
                <span className="truncate max-w-[150px]">{title || t('media.playingMedia')}</span>
              </div>
              <div className="flex items-center gap-1">
                <Button
                  variant="ghost"
                  size="icon"
                  className={cn(
                    'h-7 w-7 rounded-full transition-colors',
                    colorVariant === 'primary'
                      ? 'text-primary-foreground/70 hover:bg-destructive/20 hover:text-destructive-foreground'
                      : 'text-muted-foreground hover:bg-destructive/10 hover:text-destructive'
                  )}
                  onClick={onCloseMedia || onClose}
                  title={t('common.close')}
                  aria-label={t('media.closePlayer')}
                >
                  <X className="w-4 h-4" />
                </Button>
              </div>
            </div>

            <div
              className={cn(
                'flex-1 relative overflow-hidden group',
                enablePadding && 'p-2',
                colorVariant === 'primary' ? 'bg-primary' : 'bg-card'
              )}
            >
              {children}
            </div>
          </div>

          {/* Resize handles — mouse-only, hidden from assistive tech */}
          <div
            aria-hidden="true"
            className="absolute top-0 left-0 w-2 h-full cursor-ew-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'left')}
          />
          <div
            aria-hidden="true"
            className="absolute top-0 right-0 w-2 h-full cursor-ew-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'right')}
          />
          <div
            aria-hidden="true"
            className="absolute top-0 left-0 w-full h-2 cursor-ns-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'top')}
          />
          <div
            aria-hidden="true"
            className="absolute bottom-0 left-0 w-full h-2 cursor-ns-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'bottom')}
          />
          <div
            aria-hidden="true"
            className="absolute top-0 left-0 w-4 h-4 cursor-nwse-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'top-left')}
          />
          <div
            aria-hidden="true"
            className="absolute top-0 right-0 w-4 h-4 cursor-nesw-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'top-right')}
          />
          <div
            aria-hidden="true"
            className="absolute bottom-0 left-0 w-4 h-4 cursor-nesw-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'bottom-left')}
          />
          <div
            aria-hidden="true"
            className="absolute bottom-0 right-0 w-4 h-4 cursor-nwse-resize hover:bg-primary/20 transition-colors"
            onMouseDown={e => handleResizeStart(e, 'bottom-right')}
          />
        </div>
      </div>
    </div>
  );
}
