'use client';

import React, { useEffect, useRef, useState, useCallback } from 'react';
import dynamic from 'next/dynamic';
import * as Y from 'yjs';
import { WebsocketProvider } from 'y-websocket';
import { ExcalidrawBinding } from 'y-excalidraw';
import type { ExcalidrawImperativeAPI, ExcalidrawProps } from '@excalidraw/excalidraw/types/types';

const Excalidraw = dynamic<ExcalidrawProps & { isMentor?: boolean }>(
  async () => {
    const mod = await import('@excalidraw/excalidraw');
    const setLang = (mod as Record<string, unknown>).setLanguage;
    if (typeof setLang === 'function') {
      await setLang({ code: 'ru-RU', label: 'Русский' });
    }
    const Comp = ((mod as { Excalidraw?: React.ComponentType }).Excalidraw ?? mod.default) as React.ComponentType<ExcalidrawProps>;
    const Footer = (mod as { Footer?: React.ComponentType }).Footer;
    const MainMenu = (mod as unknown as { MainMenu?: React.ComponentType & { DefaultItems?: Record<string, React.ComponentType> } }).MainMenu;
    const EmptyFooter = Footer ? React.createElement(Footer as React.ComponentType, null, null) : null;
    const Wrapper = (props: ExcalidrawProps & { isMentor?: boolean }) => {
      const isMentor = props.isMentor === true;
      const { isMentor: _, ...excalidrawProps } = props;
      const menuItems = MainMenu?.DefaultItems
        ? [
            React.createElement(MainMenu.DefaultItems.LoadScene),
            React.createElement(MainMenu.DefaultItems.SaveToActiveFile),
            React.createElement(MainMenu.DefaultItems.SaveAsImage),
            React.createElement(MainMenu.DefaultItems.Help),
            ...(isMentor ? [React.createElement(MainMenu.DefaultItems.ClearCanvas)] : []),
            React.createElement(MainMenu.DefaultItems.ToggleTheme),
            React.createElement(MainMenu.DefaultItems.ChangeCanvasBackground),
            React.createElement(MainMenu.DefaultItems.Export),
          ]
        : [];
      const MenuWithoutSocials = menuItems.length > 0
        ? React.createElement(MainMenu!, null, ...menuItems)
        : null;
      return React.createElement(Comp, excalidrawProps, MenuWithoutSocials, EmptyFooter);
    };
    return Wrapper as React.ComponentType;
  },
  { ssr: false }
);

/**
 * Доска полностью на Yjs: синхронизация + сохранение в файлы (LevelDB на сервере).
 * Без REST API — никаких запросов к Django/PostgreSQL для содержимого доски.
 */
export default function ExcalidrawPage() {
  const [boardId, setBoardId] = useState<string | null>(null);
  const [wsUrl, setWsUrl] = useState('');
  const [username, setUsername] = useState('Пользователь');
  const [isMentor, setIsMentor] = useState(false);
  const [ready, setReady] = useState(false);
  const [wsStatus, setWsStatus] = useState<'connecting' | 'connected' | 'disconnected'>('disconnected');

  const excalidrawRef = useRef<HTMLDivElement>(null);
  const ydocRef = useRef<Y.Doc | null>(null);
  const providerRef = useRef<WebsocketProvider | null>(null);
  const bindingRef = useRef<ExcalidrawBinding | null>(null);

  // Палитра цветов для курсоров (как в y-excalidraw demo)
  const USER_COLORS = [
    { color: '#30bced', light: '#30bced33' },
    { color: '#6eeb83', light: '#6eeb8333' },
    { color: '#ffbc42', light: '#ffbc4233' },
    { color: '#ee6352', light: '#ee635233' },
    { color: '#9ac2c9', light: '#9ac2c933' },
  ];

  const decodeName = (raw: string): string => {
    if (!raw || typeof raw !== 'string') return raw;
    try {
      if (/%[0-9A-Fa-f]{2}/.test(raw)) return decodeURIComponent(raw);
      return raw;
    } catch {
      return raw;
    }
  };

  // Параметры из URL
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const id = params.get('boardId');
    const api = params.get('apiUrl') || 'http://127.0.0.1:8123';
    const token = params.get('token') || '';
    setIsMentor(params.get('isMentor') === '1');

    setBoardId(id);

    // Yjs: через nginx /yjs (prod) или прямой порт (dev/localhost)
    const apiHost = new URL(api).hostname;
    const isLocalhost = apiHost === 'localhost' || apiHost === '127.0.0.1';
    const wsProtocol = api.startsWith('https') ? 'wss:' : 'ws:';
    const yjsPort = params.get('yjsPort') || '1234';
    // Prod: через nginx /yjs (без порта), Dev: прямой порт
    const wsUrl = isLocalhost
      ? `${wsProtocol}//${apiHost}:${yjsPort}`
      : `${wsProtocol}//${apiHost}/yjs`;
    setWsUrl(wsUrl);

    // Имя из API (UTF-8, без проблем с кодировкой URL/postMessage)
    if (token) {
      fetch(`${api}/api/profile/me/`, { headers: { Authorization: `Bearer ${token}` } })
        .then((r) => r.json())
        .then((u: { first_name?: string; last_name?: string; email?: string }) => {
          const raw = `${u.first_name || ''} ${u.last_name || ''}`.trim() || u.email || 'Пользователь';
          setUsername(decodeName(raw));
        })
        .catch(() => setUsername('Пользователь'));
    } else {
      setUsername('Пользователь');
    }
  }, []);

  // Username через postMessage от родителя (резерв, если API не сработал)
  useEffect(() => {
    const handler = (e: MessageEvent) => {
      if (e.data?.type === 'excalidraw-username' && typeof e.data.username === 'string' && e.data.username) {
        setUsername(decodeName(e.data.username));
      }
    };
    window.addEventListener('message', handler);
    return () => window.removeEventListener('message', handler);
  }, []);

  // Запретить студенту Ctrl+Delete / Ctrl+Backspace (очистить холст). Не блокируем при редактировании текста.
  useEffect(() => {
    if (isMentor) return;
    const handler = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement | null;
      const isEditingText = target?.tagName === 'INPUT' || target?.tagName === 'TEXTAREA' || target?.isContentEditable;
      if (isEditingText) return;
      if ((e.ctrlKey || e.metaKey) && (e.key === 'Delete' || e.key === 'Backspace')) {
        e.preventDefault();
        e.stopPropagation();
      }
    };
    window.addEventListener('keydown', handler, { capture: true });
    return () => window.removeEventListener('keydown', handler, { capture: true });
  }, [isMentor]);

  // Обновить awareness при смене username
  useEffect(() => {
    const provider = providerRef.current;
    if (!provider) return;
    const colorIndex = username.split('').reduce((a, c) => a + c.charCodeAt(0), 0) % USER_COLORS.length;
    const userColor = USER_COLORS[colorIndex];
    provider.awareness.setLocalStateField('user', {
      name: username,
      color: userColor.color,
      colorLight: userColor.light,
    });
  }, [username]);

  // Инициализация Yjs — подключаемся сразу, данные грузятся с сервера (LevelDB/файлы)
  useEffect(() => {
    if (!boardId || !wsUrl) {
      setReady(false);
      return;
    }

    const ydoc = new Y.Doc();
    ydocRef.current = ydoc;

    const roomName = `excalidraw-${boardId}`;
    const provider = new WebsocketProvider(wsUrl, roomName, ydoc, { connect: true });
    providerRef.current = provider;

    setWsStatus('connecting');
    provider.on('status', (ev: { status: string }) => {
      const s = ev.status as 'connecting' | 'connected' | 'disconnected';
      setWsStatus(s);
      console.log('[Yjs] room:', roomName, 'status:', s);
    });
    provider.on('connection-error', (ev: Event) => {
      console.error('[Yjs] connection error:', ev);
      setWsStatus('disconnected');
    });
    provider.on('sync', (synced: boolean) => {
      if (synced) {
        console.log('[Yjs] Synced');
        setReady(true);
      }
    });

    // Готовы сразу — Yjs подтянет данные при sync
    setReady(true);

    return () => {
      bindingRef.current?.destroy();
      provider.destroy();
      ydocRef.current = null;
      providerRef.current = null;
    };
  }, [boardId, wsUrl]);

  const handleExcalidrawAPIReady = useCallback((api: ExcalidrawImperativeAPI) => {
    const ydoc = ydocRef.current;
    const provider = providerRef.current;
    if (!ydoc || !provider) return;

    const yElements = ydoc.getArray<any>('elements');
    const yAssets = ydoc.getMap<any>('assets');
    const awareness = provider.awareness;

    const updateAwarenessUser = () => {
      const colorIndex = username.split('').reduce((a, c) => a + c.charCodeAt(0), 0) % USER_COLORS.length;
      const userColor = USER_COLORS[colorIndex];
      awareness.setLocalStateField('user', {
        name: username,
        color: userColor.color,
        colorLight: userColor.light,
      });
    };
    updateAwarenessUser();

    // Откладываем создание binding, чтобы DOM Excalidraw успел смонтироваться
    requestAnimationFrame(() => {
      try {
        const binding = new ExcalidrawBinding(
          yElements,
          yAssets,
          api,
          awareness,
          undefined
        );
        bindingRef.current = binding;
      } catch (err) {
        console.error('[Excalidraw Yjs] Ошибка создания binding:', err);
      }
    });
  }, [username]);

  if (!boardId) {
    return (
      <div style={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        height: '100vh',
        background: '#fff',
        color: '#333',
        fontFamily: 'system-ui',
        padding: 24,
        gap: 12,
      }}>
        <p style={{ margin: 0, fontSize: 16 }}>Укажите параметры в URL:</p>
        <code style={{ fontSize: 12, background: '#f5f5f5', padding: '8px 12px', borderRadius: 8, wordBreak: 'break-all' }}>
          ?boardId=xxx&apiUrl=http://127.0.0.1:8123
        </code>
      </div>
    );
  }

  if (!ready) {
    return (
      <div style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        height: '100vh',
        background: '#fff',
        color: '#333',
        fontFamily: 'system-ui',
      }}>
        Загрузка доски…
      </div>
    );
  }

  return (
    <div style={{ width: '100vw', height: '100vh', position: 'relative', background: '#fff' }} ref={excalidrawRef}>
      <Excalidraw
        excalidrawAPI={(api) => handleExcalidrawAPIReady(api)}
        onPointerUpdate={(payload) => bindingRef.current?.onPointerUpdate?.(payload)}
        langCode="ru-RU"
        theme="light"
        isMentor={isMentor}
        gridModeEnabled={true}
        initialData={{
          appState: { theme: 'light', gridSize: 20 },
        }}
        UIOptions={{
          canvasActions: {
            changeViewBackgroundColor: true,
            loadScene: false,
            saveToActiveFile: false,
            toggleTheme: true,
            clearCanvas: isMentor,
          },
        }}
      />
      <div style={{
        position: 'absolute',
        bottom: 12,
        right: 12,
        fontFamily: 'system-ui',
        fontSize: 12,
      }}>
        <span title={wsUrl} style={{
          padding: '4px 8px',
          borderRadius: 6,
          background: wsStatus === 'connected' ? 'rgba(0,180,0,0.8)' : wsStatus === 'connecting' ? 'rgba(255,180,0,0.8)' : 'rgba(180,0,0,0.8)',
          color: '#fff',
        }}>
          {wsStatus === 'connected' ? 'Синхронизировано' : wsStatus === 'connecting' ? 'Подключение…' : 'Нет связи'}
        </span>
      </div>
    </div>
  );
}
