import React, { useEffect, useRef, useMemo, useState } from 'react';
import { TldrawUiButton } from '@tldraw/tldraw';
import { CCShapesPanel } from './CCShapesPanel';
import { CCSlidesPanel } from './CCSlidesPanel';
import { CCFilesPanel } from './CCFilesPanel';
import { CCCabinetsPanel } from './CCCabinetsPanel';
import { CCYoutubePanel } from './CCYoutubePanel';
import { CCGraphPanel } from './CCGraphPanel';
import { CCSearchPanel } from './CCSearchPanel';
import { CCGraphNavPanel } from './navigation/CCGraphNavPanel';
import { CCTranscriptionPanel } from './CCTranscriptionPanel';
import { PANEL_DIMENSIONS, Z_INDICES } from './panel-styles';
import './panel.css';
// import { CCNavigationPanel } from './navigation/CCNavigationPanel';
import { BaseContext, ViewContext } from '../../../../../types/navigation';
// import { CCNodeSnapshotPanel } from './navigation/CCNodeSnapshotPanel';
import { useTLDraw } from '../../../../../contexts/TLDrawContext';

export const PANEL_TYPES = {
  default: [
    { id: 'cabinets', label: 'Cabinets', order: 5 },
    { id: 'navigation', label: 'Navigation', order: 10 },
    { id: 'node-snapshot', label: 'Node', order: 20 },
    { id: 'files', label: 'Files', order: 25 },
    { id: 'cc-shapes', label: 'Shapes', order: 30 },
    { id: 'transcription', label: 'Transcription', order: 35 },
    { id: 'slides', label: 'Slides', order: 40 },
    { id: 'youtube', label: 'YouTube', order: 50 },
    { id: 'graph', label: 'Graph', order: 60 },
    { id: 'search', label: 'Search', order: 70 },
  ],
} as const;

export type PanelType = typeof PANEL_TYPES.default[number]['id'];

interface BasePanelProps {
  initialPanelType?: PanelType;
  isExpanded?: boolean;
  isPinned?: boolean;
  onExpandedChange?: (expanded: boolean) => void;
  onPinnedChange?: (pinned: boolean) => void;
  currentContext?: BaseContext;
  onContextChange?: (context: BaseContext) => void;
  currentExtendedContext?: ViewContext;
  onExtendedContextChange?: (context: ViewContext) => void;
  isMenuOpen?: boolean;
  onMenuOpenChange?: (open: boolean) => void;
}

function getIconSvg(panelId: PanelType, size = '1.25rem') {
  const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round' as const, strokeLinejoin: 'round' as const };
  switch (panelId) {
    case 'cabinets':
      return (
        <svg {...common}>
          <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
          <polyline points="9 22 9 12 15 12 15 22" />
        </svg>
      );
    case 'transcription':
      return (
        <svg {...common}>
          <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
          <path d="M19 10v2a7 7 0 0 1-14 0v-2" />
          <line x1="12" y1="19" x2="12" y2="23" />
          <line x1="8" y1="23" x2="6" y2="21" />
          <line x1="16" y1="23" x2="14" y2="21" />
        </svg>
      );
    case 'cc-shapes':
      return (
        <svg {...common}>
          <rect x="3" y="3" width="7" height="7" />
          <rect x="14" y="3" width="7" height="7" />
          <rect x="14" y="14" width="7" height="7" />
          <rect x="3" y="14" width="7" height="7" />
        </svg>
      );
    case 'slides':
      return (
        <svg {...common}>
          <rect x="2" y="3" width="13" height="18" rx="2" />
          <path d="M15 8h4l3 3v7h-7V8z" />
        </svg>
      );
    case 'youtube':
      return (
        <svg {...common}>
          <rect x="2" y="4" width="20" height="16" rx="4" />
          <polygon points="10 8 16 12 10 16 10 8" fill="currentColor" stroke="none" />
        </svg>
      );
    case 'graph':
      return (
        <svg {...common}>
          <circle cx="18" cy="5" r="3" />
          <circle cx="6" cy="12" r="3" />
          <circle cx="18" cy="19" r="3" />
          <line x1="8.59" y1="13.51" x2="15.42" y2="17.49" />
          <line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
        </svg>
      );
    case 'search':
      return (
        <svg {...common}>
          <circle cx="11" cy="11" r="8" />
          <line x1="21" y1="21" x2="16.65" y2="16.65" />
        </svg>
      );
    case 'navigation':
      return (
        <svg {...common}>
          <polygon points="3 11 22 2 13 21 11 13 3 11" />
        </svg>
      );
    case 'node-snapshot':
      return (
        <svg {...common}>
          <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" />
        </svg>
      );
    default:
      return (
        <svg {...common}>
          <rect x="3" y="3" width="18" height="18" rx="2" />
        </svg>
      );
  }
}

function isDarkMode() {
  if (typeof window === 'undefined') return false;
  return document.documentElement.dataset.colorMode === 'dark' ||
    window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
}

export const BasePanel: React.FC<BasePanelProps> = ({
  initialPanelType = 'files',
  isExpanded: controlledIsExpanded,
  isPinned: controlledIsPinned,
  onExpandedChange,
  onPinnedChange,
  isMenuOpen = false,
  onMenuOpenChange = () => {},
}) => {
  const { tldrawPreferences } = useTLDraw();
  const [prefersDarkMode, setPrefersDarkMode] = useState(isDarkMode());
  const [menuOpen, setMenuOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const mq = window.matchMedia('(prefers-color-scheme: dark)');
    const handler = () => setPrefersDarkMode(isDarkMode());
    mq.addEventListener?.('change', handler);
    return () => mq.removeEventListener?.('change', handler);
  }, []);

  const colorMode = (tldrawPreferences?.colorScheme === 'system' ? prefersDarkMode : tldrawPreferences?.colorScheme === 'dark')
    ? 'dark'
    : 'light';

  const availablePanels = PANEL_TYPES.default;

  const [currentPanelType, setCurrentPanelType] = useState<PanelType>(initialPanelType);

  const [internalIsExpanded, setInternalIsExpanded] = useState(true);
  const [internalIsPinned, setInternalIsPinned] = useState(true);

  const isExpanded = controlledIsExpanded ?? internalIsExpanded;
  const isPinned = controlledIsPinned ?? internalIsPinned;

  const handleExpandedChange = (expanded: boolean) => {
    setInternalIsExpanded(expanded);
    onExpandedChange?.(expanded);
  };

  const handlePinToggle = () => {
    const newPinned = !isPinned;
    setInternalIsPinned(newPinned);
    onPinnedChange?.(newPinned);
  };

  const panelRef = useRef<HTMLDivElement>(null);
  const dimensions = PANEL_DIMENSIONS[currentPanelType as keyof typeof PANEL_DIMENSIONS];

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (isPinned) return;
      const isClickOutside = panelRef.current && !panelRef.current.contains(event.target as Node);
      const target = event.target as HTMLElement;
      const isPanelElement = target.closest('.panel-root, .panel-handle, .tlui-button');
      if (isClickOutside && !isPanelElement) {
        handleExpandedChange(false);
      }
    };
    if (isExpanded) {
      document.addEventListener('mousedown', handleClickOutside);
    }
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [isExpanded, isPinned]);

  const renderCurrentPanel = () => {
    switch (currentPanelType) {
      case 'cabinets':
        return <CCCabinetsPanel />;
      case 'transcription':
        return <CCTranscriptionPanel />;
      case 'files':
        return <CCFilesPanel />;
      case 'cc-shapes':
        return <CCShapesPanel />;
      case 'slides':
        return <CCSlidesPanel />;
      case 'youtube':
        return <CCYoutubePanel />;
      case 'graph':
        return <CCGraphPanel />;
      case 'search':
        return <CCSearchPanel />;
      case 'navigation':
        return <CCGraphNavPanel />;
      default:
        return null;
    }
  };

  const toggleMenu = (open: boolean) => {
    setMenuOpen(open);
    onMenuOpenChange(open);
  };

  return (
    <>
      {!isExpanded && (
        <div
          className="panel-handle"
          onClick={() => handleExpandedChange(true)}
          onTouchEnd={(e) => {
            e.stopPropagation();
            handleExpandedChange(true);
          }}
        >
          ›
        </div>
      )}

      {isExpanded && (
        <div
          ref={panelRef}
          className="panel-root"
          style={{
            top: dimensions.topOffset,
            height: `calc(100% - ${dimensions.bottomOffset})`,
            width: dimensions.width,
            zIndex: Z_INDICES.PANEL,
          }}
        >
          <div className="panel-header">
            <button
              type="button"
              className="cc-btn cc-btn--secondary cc-panel-selector"
              onClick={() => toggleMenu(!menuOpen)}
            >
              <span className="cc-btn-start-icon">
                {getIconSvg(currentPanelType)}
              </span>
              <span className="cc-btn-label">
                {availablePanels.find(p => p.id === currentPanelType)?.label}
              </span>
              <span className="cc-btn-end-icon">
                <svg width="1.25rem" height="1.25rem" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <polyline points="6 9 12 15 18 9" />
                </svg>
              </span>
            </button>

            {menuOpen && (
              <div className="cc-menu panel-type-menu" role="menu">
                {[...availablePanels]
                  .sort((a, b) => a.order - b.order)
                  .map(type => (
                    <button
                      key={type.id}
                      type="button"
                      role="menuitem"
                      className={`cc-menu-item ${type.id === currentPanelType ? 'cc-menu-item--active' : ''}`}
                      onClick={() => {
                        setCurrentPanelType(type.id as PanelType);
                        toggleMenu(false);
                      }}
                    >
                      <span className="cc-menu-item-icon">
                        {getIconSvg(type.id as PanelType)}
                      </span>
                      <span className="cc-menu-item-text">
                        <span className="cc-menu-item-primary">{type.label}</span>
                        <span className="cc-menu-item-secondary">
                          {type.id === 'cabinets' && 'Manage file cabinets'}
                          {type.id === 'transcription' && 'Record and transcribe lessons'}
                          {type.id === 'cc-shapes' && 'Add shapes and elements to your canvas'}
                          {type.id === 'slides' && 'Manage presentation slides'}
                          {type.id === 'youtube' && 'Embed YouTube videos'}
                          {type.id === 'graph' && 'View and manage graph connections'}
                          {type.id === 'search' && 'Search through your content'}
                          {type.id === 'navigation' && 'Navigate through different contexts'}
                          {type.id === 'node-snapshot' && 'Manage node snapshots'}
                        </span>
                      </span>
                    </button>
                  ))}
              </div>
            )}

            <div className="panel-header-actions">
              <TldrawUiButton
                type="icon"
                onClick={handlePinToggle}
                className="pin-button"
              >
                <span className="cc-icon-button">
                  <svg
                    width="1.25rem"
                    height="1.25rem"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  >
                    {isPinned ? (
                      <>
                        <path d="M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22 12 18.56 5.82 22 7 14.14l-5-4.87 6.91-1.01L12 2z" />
                      </>
                    ) : (
                      <>
                        <circle cx="12" cy="12" r="10" />
                        <path d="M7.5 7.5l9 9" />
                      </>
                    )}
                  </svg>
                </span>
              </TldrawUiButton>
            </div>
          </div>

          <div className="panel-content">
            {renderCurrentPanel()}
          </div>
        </div>
      )}
    </>
  );
};
