'use client';

import { useEffect, useRef } from 'react';
import { useResolvedTheme } from '@djangocfg/ui-core/hooks';

/**
 * Hook that syncs Monaco editor theme with the app theme.
 *
 * Reads CSS variables from the document and creates custom Monaco themes
 * that match the current light/dark mode. Falls back to built-in 'vs' / 'vs-dark'.
 *
 * @param monaco - Monaco namespace (null during loading)
 * @param themeOverride - Optional explicit theme name (skips auto-detection)
 * @returns Resolved Monaco theme name to pass to editor options
 */
export function useEditorTheme(
  monaco: typeof import('monaco-editor') | null,
  themeOverride?: string,
): string {
  const appTheme = useResolvedTheme();
  const registered = useRef(false);

  // Register custom themes once Monaco is loaded
  useEffect(() => {
    if (!monaco || registered.current) return;

    try {
      const colors = _readCSSColors();

      monaco.editor.defineTheme('app-dark', {
        base: 'vs-dark',
        inherit: true,
        rules: [
          { token: 'comment', foreground: '6A9955', fontStyle: 'italic' },
          { token: 'keyword', foreground: 'C586C0' },
          { token: 'string', foreground: 'CE9178' },
          { token: 'number', foreground: 'B5CEA8' },
          { token: 'type', foreground: '4EC9B0' },
          { token: 'function', foreground: 'DCDCAA' },
          { token: 'variable', foreground: '9CDCFE' },
        ],
        colors: {
          'editor.background': colors.background,
          'editor.foreground': colors.foreground,
          'editor.lineHighlightBackground': colors.lineHighlight,
          'editor.selectionBackground': colors.selection,
          'editorCursor.foreground': colors.foreground,
          'editorLineNumber.foreground': colors.mutedForeground,
          'editorWidget.background': colors.card,
          'editorWidget.border': colors.border,
          'input.background': colors.card,
          'dropdown.background': colors.card,
        },
      });

      monaco.editor.defineTheme('app-light', {
        base: 'vs',
        inherit: true,
        rules: [
          { token: 'comment', foreground: '008000', fontStyle: 'italic' },
          { token: 'keyword', foreground: 'AF00DB' },
          { token: 'string', foreground: 'A31515' },
          { token: 'number', foreground: '098658' },
          { token: 'type', foreground: '267F99' },
          { token: 'function', foreground: '795E26' },
          { token: 'variable', foreground: '001080' },
        ],
        colors: {
          'editor.background': colors.backgroundLight,
          'editor.foreground': colors.foregroundLight,
          'editor.lineHighlightBackground': colors.lineHighlightLight,
          'editor.selectionBackground': colors.selectionLight,
          'editorLineNumber.foreground': colors.mutedForegroundLight,
          'editorWidget.background': colors.cardLight,
          'editorWidget.border': colors.borderLight,
        },
      });

      registered.current = true;
    } catch {
      // Fallback — use built-in themes
    }
  }, [monaco]);

  // If explicit override provided, use it
  if (themeOverride) return themeOverride;

  // Use registered app themes if available, fallback to built-in
  if (registered.current) {
    return appTheme === 'dark' ? 'app-dark' : 'app-light';
  }
  return appTheme === 'dark' ? 'vs-dark' : 'vs';
}


/** Read CSS variables and convert HSL to hex for Monaco */
function _readCSSColors() {
  const get = (varName: string): string => {
    if (typeof document === 'undefined') return '';
    return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
  };

  const hslToHex = (hsl: string): string => {
    if (!hsl) return '';
    // CSS vars are "0 0% 96%" — strip % before parsing
    const parts = hsl.split(/\s+/).map(s => parseFloat(s.replace('%', '')));
    if (parts.length < 3 || parts.some(isNaN)) return '';
    const [h, s, l] = [parts[0], parts[1] / 100, parts[2] / 100];

    const a = s * Math.min(l, 1 - l);
    const f = (n: number) => {
      const k = (n + h / 30) % 12;
      const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
      return Math.round(255 * color).toString(16).padStart(2, '0');
    };
    return `#${f(0)}${f(8)}${f(4)}`;
  };

  // Read current (dark) theme CSS variables
  const background = hslToHex(get('--background')) || '#0a0a0a';
  const foreground = hslToHex(get('--foreground')) || '#f5f5f5';
  const card = hslToHex(get('--card')) || '#141414';
  const border = hslToHex(get('--border')) || '#262626';
  const mutedForeground = hslToHex(get('--muted-foreground')) || '#858585';

  // Compute derived colors
  const lineHighlight = _adjustBrightness(background, 10);
  const primary = hslToHex(get('--primary'));
  const selection = primary ? _adjustBrightness(primary, -40) : '#264F78';

  // Light theme colors (hardcoded since we can't switch CSS context)
  return {
    background,
    foreground,
    card,
    border,
    mutedForeground,
    lineHighlight,
    selection,
    // Light variants
    backgroundLight: '#ffffff',
    foregroundLight: '#1a1a1a',
    cardLight: '#ffffff',
    borderLight: '#e5e5e5',
    mutedForegroundLight: '#737373',
    lineHighlightLight: '#f5f5f5',
    selectionLight: '#ADD6FF',
  };
}

function _adjustBrightness(hex: string, amount: number): string {
  const num = parseInt(hex.replace('#', ''), 16);
  const r = Math.min(255, Math.max(0, ((num >> 16) & 0xff) + amount));
  const g = Math.min(255, Math.max(0, ((num >> 8) & 0xff) + amount));
  const b = Math.min(255, Math.max(0, (num & 0xff) + amount));
  return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}`;
}

