'use client'

import React, { useState, useEffect } from 'react'
import Editor from '@monaco-editor/react'
import {
  Download,
  SidebarSimple,
  FileCode,
  CaretDown,
  FloppyDisk
} from '@phosphor-icons/react'
import Window from './Window'

interface FlutterRunnerProps {
  onClose: () => void
  onMinimize?: () => void
  onMaximize?: () => void
  onFocus?: () => void
  zIndex?: number
  initialCode?: string
}

interface FileNode {
  id: string
  name: string
  type: 'file' | 'folder'
  content?: string
  children?: FileNode[]
  isOpen?: boolean
}

const DEFAULT_FLUTTER_CODE = ``

export function FlutterRunner({ onClose, onMinimize, onMaximize, onFocus, zIndex, initialCode }: FlutterRunnerProps) {
  const [code, setCode] = useState(initialCode || DEFAULT_FLUTTER_CODE)
  const [showEditor, setShowEditor] = useState(true)
  const [showFiles, setShowFiles] = useState(true)
  const [files, setFiles] = useState<FileNode[]>([])
  const [activeFileId, setActiveFileId] = useState('main')
  const [activeFileName, setActiveFileName] = useState('main.dart')
  const [lastSaved, setLastSaved] = useState<Date | null>(null)
  const [passkey, setPasskey] = useState('')
  const [loading, setLoading] = useState(false)

  // Load all files for the file tree without changing the active file
  const loadAllFilesForTree = async (key: string, currentFileName: string) => {
    try {
      const response = await fetch(`/api/data?key=${encodeURIComponent(key)}&folder=`)
      const data = await response.json()

      if (data.error) {
        throw new Error(data.error)
      }

      // Filter for .dart files
      const dartFiles = data.files?.filter((f: any) => f.name.endsWith('.dart')) || []

      if (dartFiles.length > 0) {
        const fileNodes: FileNode[] = dartFiles.map((file: any, index: number) => ({
          id: `file_${index}`,
          name: file.name,
          type: 'file' as const,
          content: file.content
        }))

        setFiles([{
          id: 'root',
          name: 'Dart Files',
          type: 'folder',
          isOpen: true,
          children: fileNodes
        }])

        // Set active file ID to match the current file
        const currentFileNode = fileNodes.find(f => f.name === currentFileName)
        if (currentFileNode) {
          setActiveFileId(currentFileNode.id)
        }
      } else {
        // No files found, just show the current file
        setFiles([{
          id: 'root',
          name: 'lib',
          type: 'folder',
          isOpen: true,
          children: [
            { id: 'main', name: currentFileName, type: 'file', content: '' }
          ]
        }])
      }
    } catch (err) {
      console.error('Error loading file tree:', err)
      // On error, just show the current file
      setFiles([{
        id: 'root',
        name: 'lib',
        type: 'folder',
        isOpen: true,
        children: [
          { id: 'main', name: currentFileName, type: 'file', content: '' }
        ]
      }])
    }
  }

  // Load files from secure storage (used when no specific file is selected)
  const loadFiles = async (key: string) => {
    setLoading(true)
    try {
      const response = await fetch(`/api/data?key=${encodeURIComponent(key)}&folder=`)
      const data = await response.json()

      if (data.error) {
        throw new Error(data.error)
      }

      // Filter for .dart files
      const dartFiles = data.files?.filter((f: any) => f.name.endsWith('.dart')) || []

      if (dartFiles.length > 0) {
        const fileNodes: FileNode[] = dartFiles.map((file: any, index: number) => ({
          id: `file_${index}`,
          name: file.name,
          type: 'file' as const,
          content: file.content
        }))

        setFiles([{
          id: 'root',
          name: 'Dart Files',
          type: 'folder',
          isOpen: true,
          children: fileNodes
        }])

        // Load first file
        if (fileNodes.length > 0) {
          setActiveFileId(fileNodes[0].id)
          setActiveFileName(fileNodes[0].name)
          setCode(fileNodes[0].content || DEFAULT_FLUTTER_CODE)
        }
      } else {
        // No files found, create default
        setFiles([{
          id: 'root',
          name: 'lib',
          type: 'folder',
          isOpen: true,
          children: [
            { id: 'main', name: 'main.dart', type: 'file', content: DEFAULT_FLUTTER_CODE }
          ]
        }])
        setCode(DEFAULT_FLUTTER_CODE)
        setActiveFileName('main.dart')
      }
    } catch (err) {
      console.error('Error loading files:', err)
      // Create default on error
      setFiles([{
        id: 'root',
        name: 'lib',
        type: 'folder',
        isOpen: true,
        children: [
          { id: 'main', name: 'main.dart', type: 'file', content: DEFAULT_FLUTTER_CODE }
        ]
      }])
      setCode(DEFAULT_FLUTTER_CODE)
      setActiveFileName('main.dart')
    } finally {
      setLoading(false)
    }
  }

  const handleFileClick = (file: FileNode) => {
    if (file.type === 'file') {
      setActiveFileId(file.id)
      setActiveFileName(file.name)
      setCode(file.content || '')
    }
  }

  // Check for initial passkey and file content on mount
  useEffect(() => {
    const sessionPasskey = sessionStorage.getItem('currentPasskey')
    const sessionFileContent = sessionStorage.getItem('flutterFileContent')
    const sessionFileName = sessionStorage.getItem('currentFileName')

    if (sessionFileContent) {
      // Load file from session storage (from FileManager)
      console.log('Loading dart file from session:', sessionFileName, 'Content length:', sessionFileContent.length)
      setCode(sessionFileContent)
      setActiveFileName(sessionFileName || 'main.dart')

      if (sessionPasskey) {
        setPasskey(sessionPasskey)
        // Don't call loadFiles here - it would overwrite the file we just loaded
        // Just load all files for the file tree without changing the active file
        loadAllFilesForTree(sessionPasskey, sessionFileName || 'main.dart')
      } else {
        // For public files, just set up a simple file structure
        setFiles([{
          id: 'root',
          name: 'lib',
          type: 'folder',
          isOpen: true,
          children: [
            { id: 'main', name: sessionFileName || 'main.dart', type: 'file', content: sessionFileContent }
          ]
        }])
      }

      // Clear session storage after loading
      sessionStorage.removeItem('flutterFileContent')
    } else if (sessionPasskey) {
      setPasskey(sessionPasskey)
      loadFiles(sessionPasskey)
    } else if (initialCode) {
      setCode(initialCode)
    } else {
      // Initialize with default empty file
      setFiles([{
        id: 'root',
        name: 'lib',
        type: 'folder',
        isOpen: true,
        children: [
          { id: 'main', name: 'main.dart', type: 'file', content: DEFAULT_FLUTTER_CODE }
        ]
      }])
    }
  }, [initialCode])

  // Listen for new files being loaded while the component is already open
  useEffect(() => {
    const checkForNewFile = () => {
      const sessionFileContent = sessionStorage.getItem('flutterFileContent')
      const sessionFileName = sessionStorage.getItem('currentFileName')
      const sessionPasskey = sessionStorage.getItem('currentPasskey')

      if (sessionFileContent) {
        console.log('Detected new file in session storage:', sessionFileName)
        setCode(sessionFileContent)
        setActiveFileName(sessionFileName || 'main.dart')

        if (sessionPasskey) {
          setPasskey(sessionPasskey)
          // Load all files for the file tree without overwriting the current file
          loadAllFilesForTree(sessionPasskey, sessionFileName || 'main.dart')
        } else {
          // For public files, just set up a simple file structure
          setFiles([{
            id: 'root',
            name: 'lib',
            type: 'folder',
            isOpen: true,
            children: [
              { id: 'main', name: sessionFileName || 'main.dart', type: 'file', content: sessionFileContent }
            ]
          }])
        }

        // Clear session storage after loading
        sessionStorage.removeItem('flutterFileContent')
      }
    }

    // Check every 500ms for new files
    const interval = setInterval(checkForNewFile, 500)

    return () => clearInterval(interval)
  }, [])

  // Manual save function
  const handleSave = async () => {
    if (!passkey || !activeFileName) {
      alert('Cannot save: No passkey set. This file is from public storage.')
      return
    }

    try {
      setLoading(true)
      await fetch('/api/data', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          key: passkey,
          passkey: passkey,
          action: 'save_file',
          fileName: activeFileName,
          content: code
        })
      })
      setLastSaved(new Date())
    } catch (error) {
      console.error('Save failed:', error)
      alert('Failed to save file')
    } finally {
      setLoading(false)
    }
  }

  const handleDownload = () => {
    const blob = new Blob([code], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = activeFileName || 'main.dart'
    a.click()
    URL.revokeObjectURL(url)
  }


  return (
    <Window
      id="flutter-runner"
      title="Flutter IDE"
      isOpen={true}
      onClose={onClose}
      onMinimize={onMinimize}
      onMaximize={onMaximize}
      onFocus={onFocus}
      zIndex={zIndex}
      width={1400}
      height={800}
      x={40}
      y={40}
      className="flutter-ide-window"
    >
      <div className="flex h-full bg-[#1e1e1e] text-gray-300 font-sans">
          {/* Code Editor - Conditionally Rendered */}
          {showEditor && (
            <div className="w-[600px] flex flex-col border-r border-[#333]">
              {/* Toolbar */}
              <div className="h-10 bg-[#2d2d2d] border-b border-[#1e1e1e] flex items-center justify-between px-4">
                <div className="flex items-center gap-2">
                  <button
                    onClick={() => setShowFiles(!showFiles)}
                    className={`p-1.5 rounded hover:bg-[#3e3e42] ${showFiles ? 'text-white' : 'text-gray-500'}`}
                    title="Toggle Files"
                  >
                    <SidebarSimple size={16} />
                  </button>
                  <div className="h-4 w-[1px] bg-gray-600 mx-2" />
                  <div className="flex items-center gap-2 px-3 py-1 bg-[#1e1e1e] rounded text-xs text-gray-400 border border-[#333]">
                    <FileCode size={14} className="text-blue-400" />
                    {activeFileName}
                  </div>
                  {lastSaved && (
                    <span className="text-xs text-green-400">
                      ✓ Saved {lastSaved.toLocaleTimeString()}
                    </span>
                  )}
                </div>

                <div className="flex items-center gap-2">
                  <button
                    onClick={handleSave}
                    disabled={!passkey || loading}
                    className={`p-1.5 rounded transition-colors ${
                      passkey && !loading
                        ? 'text-blue-400 hover:text-blue-300 hover:bg-[#3e3e42]'
                        : 'text-gray-600 cursor-not-allowed'
                    }`}
                    title={passkey ? "Save to Secure Storage" : "Cannot save public files"}
                  >
                    <FloppyDisk size={16} />
                  </button>
                  <button
                    onClick={handleDownload}
                    className="p-1.5 text-gray-400 hover:text-white hover:bg-[#3e3e42] rounded transition-colors"
                    title="Download Code"
                  >
                    <Download size={16} />
                  </button>
                </div>
              </div>

              {/* Monaco Editor */}
              <div className="flex-1">
                <Editor
                  height="100%"
                  defaultLanguage="dart"
                  theme="vs-dark"
                  value={code}
                  onChange={(value) => setCode(value || '')}
                  options={{
                    minimap: { enabled: false },
                    fontSize: 14,
                    fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
                    lineNumbers: 'on',
                    scrollBeyondLastLine: false,
                    automaticLayout: true,
                    padding: { top: 16, bottom: 16 },
                    renderLineHighlight: 'all',
                    smoothScrolling: true,
                    cursorBlinking: 'smooth',
                    cursorSmoothCaretAnimation: 'on'
                  }}
                />
              </div>
            </div>
          )}

          {/* DartPad Preview - Takes full width when editor is hidden */}
          <div className="flex-1 flex flex-col">
            <div className="h-10 bg-[#2d2d2d] border-b border-[#1e1e1e] flex items-center justify-between px-4">
              <button
                onClick={() => setShowEditor(!showEditor)}
                className={`flex items-center gap-2 px-2 py-1 rounded transition-all ${showEditor
                  ? 'bg-[#3e3e42] text-white hover:bg-[#4e4e52]'
                  : 'bg-blue-600 text-white hover:bg-blue-700'}`}
                title={showEditor ? "Hide Code Editor" : "Show Code Editor"}
              >
                <SidebarSimple size={16} weight={showEditor ? "fill" : "regular"} />
                <span className="text-xs font-medium">
                  {showEditor ? "Hide Editor" : "Show Editor"}
                </span>
              </button>
              <span className="text-xs text-gray-400 uppercase font-bold">
                Live Preview {!showEditor && "- Full Screen"}
              </span>
              <div className="w-24" /> {/* Spacer for centering */}
            </div>
            <div className="flex-1 bg-[#1e1e1e] relative overflow-hidden">
              <iframe

                src="https://dartpad.dev/embed-flutter.html?theme=dark&split=50"
                className="w-full h-full border-0"
                sandbox="allow-scripts allow-same-origin allow-popups"
                title="Flutter Preview"
              />
            </div>
          </div>

          {/* File List - Right Side - Only show when editor is visible */}
          {showEditor && showFiles && (
            <div className="w-64 bg-[#252526] border-l border-[#333] flex flex-col">
              <div className="h-9 px-4 flex items-center text-xs font-bold text-gray-500 uppercase tracking-wider">
                Project Files
              </div>
              <div className="flex-1 overflow-y-auto py-2">
                <div className="px-2">
                  <div className="flex items-center gap-1 py-1 px-2 text-sm text-gray-300 hover:bg-[#2a2d2e] rounded cursor-pointer">
                    <CaretDown size={12} weight="bold" />
                    <span className="font-bold">Flutter App</span>
                  </div>
                  <div className="pl-4">
                    {files.map(file => (
                      <div key={file.id}>
                        <div className="flex items-center gap-2 py-1 px-2 text-sm hover:bg-[#2a2d2e] rounded cursor-pointer text-blue-400">
                          <CaretDown size={12} weight="bold" />
                          {file.name}
                        </div>
                        {file.children?.map(child => (
                          <div
                            key={child.id}
                            onClick={() => handleFileClick(child)}
                            className={`flex items-center gap-2 py-1 px-2 ml-4 text-sm rounded cursor-pointer ${activeFileId === child.id ? 'bg-[#37373d] text-white' : 'text-gray-400 hover:bg-[#2a2d2e]'
                              }`}
                          >
                            <FileCode size={14} />
                            {child.name}
                          </div>
                        ))}
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            </div>
          )}
      </div>
    </Window>
  )
}
