import { useState, useMemo } from 'react'
import { useWaste } from '../store'
import { BrowserAdapter } from '../adapter/browser'
import type { FileEntry } from '../types'

function fmt(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`
}

type SortKey = 'name' | 'size'
type SortDir = 'asc' | 'desc'

interface DirEntry {
  kind: 'dir'
  name: string
  path: string
  count: number
}

interface FileRow {
  kind: 'file'
  name: string
  path: string
  size: number
}

type Row = DirEntry | FileRow

function buildRows(files: FileEntry[], cwd: string, search: string, sort: SortKey, sortDir: SortDir): Row[] {
  // Filter to entries under cwd
  const prefix = cwd ? cwd + '/' : ''
  const inDir = files.filter(f => {
    const p = f.path ?? f.name
    return p.startsWith(prefix)
  })

  if (search.trim()) {
    // Flat search across all files under cwd
    const q = search.toLowerCase()
    return inDir
      .filter(f => f.name.toLowerCase().includes(q))
      .map(f => ({ kind: 'file' as const, name: f.name, path: f.path ?? f.name, size: f.size_bytes }))
      .sort((a, b) => {
        const cmp = sort === 'name' ? a.name.localeCompare(b.name) : a.size - b.size
        return sortDir === 'asc' ? cmp : -cmp
      })
  }

  // Build immediate children: dirs and files at this level
  const dirs = new Map<string, number>() // dirName → file count
  const fileRows: FileRow[] = []

  for (const f of inDir) {
    const rel = (f.path ?? f.name).slice(prefix.length)
    const slash = rel.indexOf('/')
    if (slash === -1) {
      fileRows.push({ kind: 'file', name: f.name, path: f.path ?? f.name, size: f.size_bytes })
    } else {
      const dirName = rel.slice(0, slash)
      dirs.set(dirName, (dirs.get(dirName) ?? 0) + 1)
    }
  }

  const dirRows: DirEntry[] = Array.from(dirs.entries()).map(([name, count]) => ({
    kind: 'dir', name, path: prefix + name, count,
  }))

  // Sort each group separately, then dirs first
  const cmpFiles = (a: FileRow, b: FileRow) => {
    const cmp = sort === 'name' ? a.name.localeCompare(b.name) : a.size - b.size
    return sortDir === 'asc' ? cmp : -cmp
  }
  dirRows.sort((a, b) => a.name.localeCompare(b.name))
  fileRows.sort(cmpFiles)

  return [...dirRows, ...fileRows]
}

export function FileBrowser() {
  const { activeFilePeer, fileLists, setActiveFilePeer, adapter, connectedPeers } = useWaste()
  const [cwd, setCwd] = useState('')
  const [search, setSearch] = useState('')
  const [sort, setSort] = useState<SortKey>('name')
  const [sortDir, setSortDir] = useState<SortDir>('asc')

  if (!activeFilePeer) return null

  const peer = connectedPeers.find(p => p.id === activeFilePeer)
  const files = fileLists[activeFilePeer] ?? null

  function download(path: string) {
    if (adapter instanceof BrowserAdapter) {
      adapter.requestGet(activeFilePeer!, path)
    }
  }

  function toggleSort(key: SortKey) {
    if (sort === key) setSortDir(d => d === 'asc' ? 'desc' : 'asc')
    else { setSort(key); setSortDir('asc') }
  }

  function navigateUp() {
    const parts = cwd.split('/')
    parts.pop()
    setCwd(parts.join('/'))
  }

  const rows = useMemo(() => {
    if (!files) return []
    return buildRows(files, cwd, search, sort, sortDir)
  }, [files, cwd, search, sort, sortDir])

  const cwdParts = cwd ? cwd.split('/') : []

  return (
    <div className="file-browser">
      <div className="file-browser-header">
        <span className="file-browser-title">Files · {peer?.alias ?? activeFilePeer.slice(0, 8)}</span>
        <button className="file-browser-close" onClick={() => setActiveFilePeer(null)}>✕</button>
      </div>

      {files === null ? (
        <div className="file-browser-empty">Loading…</div>
      ) : files.length === 0 ? (
        <div className="file-browser-empty">No files shared</div>
      ) : (
        <>
          <div className="file-browser-toolbar">
            <input
              className="file-browser-search"
              value={search}
              onChange={e => setSearch(e.target.value)}
              placeholder="search…"
            />
          </div>

          {/* Breadcrumb */}
          <div className="file-browser-breadcrumb">
            <button onClick={() => setCwd('')} className="breadcrumb-seg">~</button>
            {cwdParts.map((seg, i) => (
              <span key={i}>
                <span className="breadcrumb-sep">/</span>
                <button
                  className="breadcrumb-seg"
                  onClick={() => setCwd(cwdParts.slice(0, i + 1).join('/'))}
                >{seg}</button>
              </span>
            ))}
          </div>

          {/* Sort bar */}
          <div className="file-browser-sortbar">
            <button className={`sort-btn ${sort === 'name' ? 'active' : ''}`} onClick={() => toggleSort('name')}>
              name {sort === 'name' ? (sortDir === 'asc' ? '↑' : '↓') : ''}
            </button>
            <button className={`sort-btn ${sort === 'size' ? 'active' : ''}`} onClick={() => toggleSort('size')}>
              size {sort === 'size' ? (sortDir === 'asc' ? '↑' : '↓') : ''}
            </button>
          </div>

          <ul className="file-list">
            {cwd && !search && (
              <li className="file-entry file-entry-dir" onClick={navigateUp}>
                <span className="file-entry-icon">📁</span>
                <span className="file-entry-name">..</span>
              </li>
            )}
            {rows.length === 0 && (
              <li className="file-browser-empty">no results</li>
            )}
            {rows.map(row => row.kind === 'dir' ? (
              <li key={row.path} className="file-entry file-entry-dir" onClick={() => { setCwd(row.path); setSearch('') }}>
                <span className="file-entry-icon">📁</span>
                <span className="file-entry-name">{row.name}</span>
                <span className="file-entry-size">{row.count} file{row.count !== 1 ? 's' : ''}</span>
              </li>
            ) : (
              <li key={row.path} className="file-entry">
                <span className="file-entry-icon">📄</span>
                <span className="file-entry-name">{row.name}</span>
                <span className="file-entry-size">{fmt(row.size)}</span>
                <button className="file-entry-dl" onClick={() => download(row.path)}>↓</button>
              </li>
            ))}
          </ul>
        </>
      )}
    </div>
  )
}
