'use client'

import dynamic from 'next/dynamic'
import { useState, useEffect, useRef } from 'react'
import { toast } from 'sonner'
import type { ExcalidrawElement } from '@excalidraw/excalidraw/types/element/types'
import type { AppState, BinaryFiles } from '@excalidraw/excalidraw/types/types'
import '@excalidraw/excalidraw/index.css'

// Dynamic import with SSR disabled is REQUIRED for Excalidraw due to window dependencies
const Excalidraw = dynamic(
  async () => (await import('@excalidraw/excalidraw')).Excalidraw,
  { ssr: false }
)

interface CanvasBoardProps {
  initialData?: string
  canvasId?: string
  name: string
}

export function CanvasBoard({ initialData, canvasId, name }: CanvasBoardProps) {
  const [isDarkMode, setIsDarkMode] = useState(false)
  const [saveStatus, setSaveStatus] = useState<'saved' | 'saving' | 'error'>('saved')
  const saveTimeoutRef = useRef<NodeJS.Timeout | null>(null)
  const filesRef = useRef<BinaryFiles>({})

  // Parse initial state safely (ONLY ON MOUNT to prevent Next.js revalidation infinite loops)
  const [elements] = useState<readonly ExcalidrawElement[]>(() => {
    if (initialData) {
      try {
        const parsed = JSON.parse(initialData)
        if (parsed && Array.isArray(parsed)) {
            return parsed
        } else if (parsed && parsed.elements) {
            // Restore binary files if present
            if (parsed.files && typeof parsed.files === 'object') {
              filesRef.current = parsed.files
            }
            return parsed.elements
        }
      } catch (e) {
        console.error("[CanvasBoard] Failed to parse initial Excalidraw data:", e)
      }
    }
    return []
  })

  // Detect dark mode from html class
  useEffect(() => {
    const checkDarkMode = () => {
      const isDark = document.documentElement.classList.contains('dark')
      setIsDarkMode(isDark)
    }

    checkDarkMode()

    // Observer for theme changes
    const observer = new MutationObserver(checkDarkMode)
    observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] })

    return () => observer.disconnect()
  }, [])

  const handleChange = (
    excalidrawElements: readonly ExcalidrawElement[],
    appState: AppState,
    files: BinaryFiles
  ) => {
    // Keep files ref up to date so we can include them in the save payload
    if (files) filesRef.current = files

    if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)

    setSaveStatus('saving')
    saveTimeoutRef.current = setTimeout(async () => {
      try {
        // Save both elements and binary files so images persist across page changes
        const snapshot = JSON.stringify({ elements: excalidrawElements, files: filesRef.current })
        await fetch('/api/canvas', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id: canvasId || null, name, data: snapshot })
        })
        setSaveStatus('saved')
      } catch (e) {
        console.error("[CanvasBoard] Save failure:", e)
        setSaveStatus('error')
      }
    }, 2000)
  }

  return (
    <div className="absolute inset-0 h-full w-full bg-slate-50 dark:bg-[#121212]" dir="ltr">
      <Excalidraw
        initialData={{ elements, files: filesRef.current }}
        theme={isDarkMode ? "dark" : "light"}
        onChange={handleChange}
        libraryReturnUrl={typeof window !== 'undefined' ? window.location.origin + window.location.pathname + window.location.search : undefined}
        UIOptions={{
          canvasActions: {
            loadScene: false,
            saveToActiveFile: false,
            clearCanvas: true
          }
        }}
      />
    </div>
  )
}
