import { useState, useEffect, useMemo } from 'react'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { X, Folder, AlertCircle } from 'lucide-react'
import clsx from 'clsx'
import {
  heaps as heapsApi,
  type Heap,
  type FolderTreeNode,
} from '../../services/api'
import { HEAPS_QUERY_KEY } from '../../hooks/useHeapsQuery'
import { useFolderTreeQuery } from '../../hooks/useFolderTreeQuery'
import { toast } from '../ToastContainer'

interface FlatFolder {
  id: string
  name: string
  path: string
  depth: number
}

/** Walk the folder tree depth-first into a flat list with depth info so
 *  the picker can render every node — including nested subfolders — as
 *  one indented option. */
function flattenTree(nodes: FolderTreeNode[], depth = 0): FlatFolder[] {
  const out: FlatFolder[] = []
  for (const n of nodes) {
    out.push({ id: n.id, name: n.name, path: n.path, depth })
    if (n.children.length > 0) {
      out.push(...flattenTree(n.children, depth + 1))
    }
  }
  return out
}

interface HeapConvertDialogProps {
  heap: Heap | null
  onClose: () => void
}

/**
 * Modal that converts a heap into a folder. The user picks a target folder
 * (any source root, today — sub-folder picking is a follow-up), chooses
 * move vs copy semantics, and optionally has the heap deleted on success.
 */
export function HeapConvertDialog({ heap, onClose }: HeapConvertDialogProps) {
  const queryClient = useQueryClient()
  const [targetId, setTargetId] = useState('')
  const [mode, setMode] = useState<'move' | 'copy'>('move')
  const [deleteHeap, setDeleteHeap] = useState(false)
  const [subfolderName, setSubfolderName] = useState('')

  // Use the recursive folder tree, not the flat source-root list, so the
  // user can pick a sub-folder at any depth as the target.
  const { data: tree = [] } = useFolderTreeQuery()
  const folders = useMemo<FlatFolder[]>(() => flattenTree(tree), [tree])

  // Default to the first folder when the dialog opens or folders load.
  useEffect(() => {
    if (!targetId && folders.length > 0) {
      setTargetId(folders[0].id)
    }
  }, [folders, targetId])

  // Reset state on close, prefill subfolder name when opened.
  useEffect(() => {
    if (heap) {
      setSubfolderName(heap.name)
    } else {
      setTargetId('')
      setMode('move')
      setDeleteHeap(false)
      setSubfolderName('')
    }
  }, [heap])

  const convertMutation = useMutation({
    mutationFn: () =>
      heapsApi.convert(heap!.id, {
        target_id: targetId,
        mode,
        delete_heap: deleteHeap,
        // Empty subfolder = drop directly into the parent. Trim and only
        // send if the user kept it populated.
        subfolder_name: subfolderName.trim() || null,
      }),
    onSuccess: (data) => {
      const total = (data.moved ?? 0) + (data.copied ?? 0)
      const verb = data.mode === 'move' ? 'Moved' : 'Copied'
      toast.success(
        `${verb} ${total} photo${total === 1 ? '' : 's'}`,
        data.heap_deleted ? `Heap "${heap?.name}" deleted` : undefined
      )
      queryClient.invalidateQueries({ queryKey: HEAPS_QUERY_KEY })
      queryClient.invalidateQueries({ queryKey: ['photos'] })
      queryClient.invalidateQueries({ queryKey: ['folders'] })
      onClose()
    },
    onError: (e: any) =>
      toast.error('Convert failed', e?.response?.data?.detail || e.message),
  })

  if (!heap) return null

  const targetFolder = folders.find((f) => f.id === targetId)

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose} />

      <div className="relative z-10 w-full max-w-md rounded-lg border border-border bg-surface p-6 shadow-xl">
        <div className="mb-4 flex items-center justify-between">
          <h2 className="text-lg font-semibold text-text">
            Convert "{heap.name}" to folder
          </h2>
          <button
            onClick={onClose}
            disabled={convertMutation.isPending}
            className="rounded p-1 text-text-muted hover:bg-surface-2 hover:text-text"
          >
            <X className="h-5 w-5" />
          </button>
        </div>

        {/* Target picker */}
        <div className="mb-4">
          <label className="mb-1 block text-xs text-text-muted">Target folder</label>
          {folders.length === 0 ? (
            <div className="rounded border border-border bg-bg px-3 py-2 text-xs text-text-muted">
              No folders available
            </div>
          ) : (
            <select
              value={targetId}
              onChange={(e) => setTargetId(e.target.value)}
              className="w-full rounded border border-border bg-bg px-2 py-1.5 text-sm text-text focus:border-primary focus:outline-none"
            >
              {folders.map((f) => (
                <option key={f.id} value={f.id}>
                  {/* Two non-breaking spaces per depth so nested
                   *  subfolders read as a tree in the native dropdown. */}
                  {'\u00A0\u00A0'.repeat(f.depth) + f.name}
                </option>
              ))}
            </select>
          )}
          {targetFolder && (
            <p className="mt-1 flex items-center gap-1 text-xs text-text-faint">
              <Folder className="h-3 w-3" />
              {targetFolder.path}
            </p>
          )}
        </div>

        {/* Subfolder name */}
        <div className="mb-4">
          <label className="mb-1 block text-xs text-text-muted">
            Subfolder name
          </label>
          <input
            type="text"
            value={subfolderName}
            onChange={(e) => setSubfolderName(e.target.value)}
            placeholder="(none — use parent directly)"
            className="w-full rounded border border-border bg-bg px-2 py-1.5 text-sm text-text placeholder-text-faint focus:border-primary focus:outline-none"
          />
          <p className="mt-1 text-xs text-text-faint">
            {subfolderName.trim() && targetFolder
              ? `Will create ${targetFolder.path}/${subfolderName.trim()} if missing.`
              : 'Photos go directly into the parent folder.'}
          </p>
        </div>

        {/* Mode toggle */}
        <div className="mb-4">
          <label className="mb-1 block text-xs text-text-muted">Mode</label>
          <div className="flex gap-2">
            <button
              onClick={() => setMode('move')}
              className={clsx(
                'flex-1 rounded px-3 py-1.5 text-sm transition-colors',
                mode === 'move'
                  ? 'bg-primary text-white'
                  : 'bg-surface-2 text-text-muted hover:bg-surface-offset hover:text-text'
              )}
            >
              Move
            </button>
            <button
              onClick={() => setMode('copy')}
              className={clsx(
                'flex-1 rounded px-3 py-1.5 text-sm transition-colors',
                mode === 'copy'
                  ? 'bg-primary text-white'
                  : 'bg-surface-2 text-text-muted hover:bg-surface-offset hover:text-text'
              )}
            >
              Copy
            </button>
          </div>
          <p className="mt-1 text-xs text-text-faint">
            {mode === 'move'
              ? 'Files are moved on disk; original photos update their folder.'
              : 'Files are copied on disk; new photo records are created.'}
          </p>
        </div>

        {/* Delete heap toggle */}
        <div className="mb-4 flex items-center gap-2">
          <input
            id="delete-heap"
            type="checkbox"
            checked={deleteHeap}
            onChange={(e) => setDeleteHeap(e.target.checked)}
            className="h-4 w-4 rounded border-border bg-bg text-primary focus:ring-2 focus:ring-primary focus:ring-offset-0"
          />
          <label htmlFor="delete-heap" className="text-sm text-text">
            Delete heap after conversion
          </label>
        </div>

        {convertMutation.isError && (
          <div className="mb-3 flex items-center gap-2 rounded bg-reject/10 p-3 text-sm text-reject">
            <AlertCircle className="h-4 w-4 flex-shrink-0" />
            <span>{(convertMutation.error as any)?.message || 'Conversion failed'}</span>
          </div>
        )}

        <div className="flex justify-end gap-2">
          <button
            onClick={onClose}
            disabled={convertMutation.isPending}
            className="rounded bg-surface-2 px-4 py-2 text-sm text-text hover:bg-surface-offset disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            onClick={() => convertMutation.mutate()}
            disabled={!targetId || convertMutation.isPending}
            className="rounded bg-primary px-4 py-2 text-sm font-medium text-white hover:bg-primary/90 disabled:opacity-50"
          >
            {convertMutation.isPending ? 'Converting…' : 'Convert'}
          </button>
        </div>
      </div>
    </div>
  )
}
