import { useEffect, useState } from 'react'
import { listLogs, readLog } from '../api/client'
import { Folder, File, ArrowLeft, Loader2, RefreshCw } from 'lucide-react'

interface LogItem {
  name: string
  is_dir: boolean
  size: number
}

function formatSize(bytes: number): string {
  if (bytes < 1024) return bytes + ' B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
  return (bytes / 1024 / 1024).toFixed(1) + ' MB'
}

export function LogsPage() {
  const [path, setPath] = useState('/')
  const [items, setItems] = useState<LogItem[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [viewingFile, setViewingFile] = useState<string | null>(null)
  const [fileContent, setFileContent] = useState('')
  const [fileLoading, setFileLoading] = useState(false)
  const [tailLines, setTailLines] = useState(500)

  const loadDir = (p: string) => {
    setLoading(true)
    setError('')
    listLogs(p)
      .then((data) => {
        setPath(data.path)
        setItems(data.items.sort((a, b) => (a.is_dir === b.is_dir ? 0 : a.is_dir ? -1 : 1)))
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    loadDir(path)
  }, [])

  useEffect(() => {
    if (viewingFile) {
      setFileLoading(true)
      readLog(viewingFile, tailLines)
        .then((data) => setFileContent(data.content))
        .catch((err) => setError(err.message))
        .finally(() => setFileLoading(false))
    }
  }, [viewingFile, tailLines])

  const handleNavigate = (item: LogItem) => {
    if (item.is_dir) {
      const newPath = path === '/' ? '/' + item.name : path + '/' + item.name
      loadDir(newPath)
    } else {
      setViewingFile(path === '/' ? item.name : path + '/' + item.name)
    }
  }

  const handleBack = () => {
    const parts = path.replace(/\/$/, '').split('/').filter(Boolean)
    if (parts.length <= 1) return
    parts.pop()
    const newPath = parts.length === 0 ? '/' : '/' + parts.join('/')
    loadDir(newPath)
  }

  const handleRefreshFile = () => {
    if (!viewingFile) return
    setFileLoading(true)
    readLog(viewingFile, tailLines)
      .then((data) => setFileContent(data.content))
      .catch((err) => setError(err.message))
      .finally(() => setFileLoading(false))
  }

  const breadcrumbs = path.split('/').filter(Boolean)
  const canGoBack = breadcrumbs.length > 0

  return (
    <div>
      <h1 className="text-2xl font-bold mb-4 text-gray-800 dark:text-white">Logs</h1>

      <div className="mb-4 flex items-center gap-2 flex-wrap">
        <button
          onClick={handleBack}
          disabled={!canGoBack}
          className="flex items-center gap-1 px-3 py-2 rounded-lg bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed"
        >
          <ArrowLeft className="w-4 h-4" />
          Back
        </button>
        <div className="flex items-center gap-1 px-3 py-2 bg-gray-100 dark:bg-gray-700 rounded-lg text-sm">
          <span className="text-gray-500">Path:</span>
          <span className="text-gray-800 dark:text-white font-mono">{path || '/'}</span>
        </div>
      </div>

      {error && (
        <div className="mb-4 p-3 rounded-lg bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300">
          {error}
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
          <div className="px-4 py-2 border-b dark:border-gray-700 text-sm font-medium text-gray-700 dark:text-gray-300">
            Log files
          </div>
          {loading ? (
            <div className="p-8 flex justify-center">
              <Loader2 className="w-8 h-8 animate-spin text-gray-400" />
            </div>
          ) : (
            <div className="divide-y divide-gray-200 dark:divide-gray-700 max-h-[500px] overflow-y-auto">
              {items.length === 0 ? (
                <div className="px-4 py-8 text-center text-gray-500">Empty directory</div>
              ) : (
                items.map((item) => (
                  <button
                    key={item.name}
                    onClick={() => handleNavigate(item)}
                    className="flex items-center gap-2 w-full px-4 py-2 text-left hover:bg-gray-50 dark:hover:bg-gray-700/50"
                  >
                    {item.is_dir ? (
                      <Folder className="w-5 h-5 text-amber-500 flex-shrink-0" />
                    ) : (
                      <File className="w-5 h-5 text-gray-400 flex-shrink-0" />
                    )}
                    <span className="text-gray-900 dark:text-white truncate">{item.name}</span>
                    {!item.is_dir && (
                      <span className="ml-auto text-gray-500 text-sm flex-shrink-0">
                        {formatSize(item.size)}
                      </span>
                    )}
                  </button>
                ))
              )}
            </div>
          )}
        </div>

        <div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden flex flex-col">
          <div className="px-4 py-2 border-b dark:border-gray-700 flex items-center justify-between gap-2">
            <span className="text-sm font-medium text-gray-700 dark:text-gray-300 truncate">
              {viewingFile || 'Select a log file'}
            </span>
            {viewingFile && (
              <div className="flex items-center gap-2 flex-shrink-0">
                <label className="text-xs text-gray-500">Lines:</label>
                <select
                  value={tailLines}
                  onChange={(e) => setTailLines(Number(e.target.value))}
                  className="text-sm border rounded px-2 py-1 bg-white dark:bg-gray-700"
                >
                  <option value={100}>100</option>
                  <option value={500}>500</option>
                  <option value={1000}>1000</option>
                  <option value={5000}>5000</option>
                  <option value={10000}>10000</option>
                </select>
                <button
                  onClick={handleRefreshFile}
                  disabled={fileLoading}
                  className="p-1.5 rounded hover:bg-gray-200 dark:hover:bg-gray-600"
                  title="Refresh"
                >
                  <RefreshCw className={`w-4 h-4 ${fileLoading ? 'animate-spin' : ''}`} />
                </button>
              </div>
            )}
          </div>
          <div className="flex-1 overflow-auto p-4 min-h-[400px]">
            {!viewingFile ? (
              <div className="text-gray-500 text-sm">Click a log file to view</div>
            ) : fileLoading ? (
              <div className="flex justify-center py-8">
                <Loader2 className="w-8 h-8 animate-spin text-gray-400" />
              </div>
            ) : (
              <pre className="font-mono text-xs text-gray-800 dark:text-gray-200 whitespace-pre-wrap break-all">
                {fileContent || '(empty)'}
              </pre>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}
