import React, { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { listPresets, savePreset, getPreset, loadPreset, deletePreset, PresetMeta } from '../api/client'

export default function PresetsPage() {
  const qc = useQueryClient()
  const [newName, setNewName] = useState('')
  const [newDescription, setNewDescription] = useState('')
  const [savingError, setSavingError] = useState('')
  const [expanded, setExpanded] = useState<string | null>(null)
  const [message, setMessage] = useState<string | null>(null)

  const { data, isLoading } = useQuery({ queryKey: ['presets'], queryFn: listPresets })

  const { data: presetDetail } = useQuery({
    queryKey: ['preset', expanded],
    queryFn: () => getPreset(expanded!),
    enabled: !!expanded,
  })

  const saveMut = useMutation({
    mutationFn: ({ name, description }: { name: string; description: string }) =>
      savePreset(name, description || undefined),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['presets'] })
      setNewName('')
      setNewDescription('')
      setSavingError('')
      setMessage('Preset saved.')
    },
    onError: (err) => setSavingError(err instanceof Error ? err.message : String(err)),
  })

  const loadMut = useMutation({
    mutationFn: (name: string) => loadPreset(name),
    onSuccess: (_, name) => {
      qc.invalidateQueries({ queryKey: ['state'] })
      qc.invalidateQueries({ queryKey: ['workflowInputs'] })
      setMessage(`Loaded preset: ${name}`)
    },
  })

  const deleteMut = useMutation({
    mutationFn: (name: string) => deletePreset(name),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['presets'] })
      setMessage('Preset deleted.')
    },
  })

  return (
    <div className="max-w-xl mx-auto space-y-6">
      <h1 className="text-xl font-bold text-gray-800 dark:text-gray-100">Presets</h1>

      {message && (
        <div className="text-sm text-blue-600 dark:text-blue-400">{message}</div>
      )}

      {/* Save current state */}
      <div className="space-y-2">
        <div className="flex flex-col sm:flex-row gap-2">
          <input
            type="text"
            value={newName}
            onChange={e => setNewName(e.target.value)}
            placeholder="Preset name"
            className="flex-1 border border-gray-300 dark:border-gray-600 rounded px-3 py-2 text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
          />
          <button
            onClick={() => { setSavingError(''); saveMut.mutate({ name: newName, description: newDescription }) }}
            disabled={!newName.trim() || saveMut.isPending}
            className="bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white rounded px-3 py-2 text-sm font-medium"
          >
            Save current state
          </button>
        </div>
        <input
          type="text"
          value={newDescription}
          onChange={e => setNewDescription(e.target.value)}
          placeholder="Description (optional)"
          className="w-full border border-gray-300 dark:border-gray-600 rounded px-3 py-2 text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
        />
      </div>
      {savingError && <p className="text-red-500 text-sm">{savingError}</p>}

      {/* Preset list */}
      {isLoading ? (
        <div className="text-sm text-gray-400">Loading presets…</div>
      ) : (data?.presets ?? []).length === 0 ? (
        <p className="text-sm text-gray-400">No presets saved yet.</p>
      ) : (
        <ul className="divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded">
          {(data?.presets ?? []).map((preset: PresetMeta) => (
            <li key={preset.name} className="px-3 py-2 space-y-1">
              <div className="flex items-center justify-between">
                <button
                  onClick={() => setExpanded(expanded === preset.name ? null : preset.name)}
                  className="text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 text-left"
                >
                  {preset.name}
                  {preset.owner && (
                    <span className="ml-2 text-xs text-gray-400 dark:text-gray-500 font-normal">
                      {preset.owner}
                    </span>
                  )}
                </button>
                <div className="flex gap-2">
                  <button
                    onClick={() => { setMessage(null); loadMut.mutate(preset.name) }}
                    disabled={loadMut.isPending}
                    className="text-xs bg-green-600 hover:bg-green-700 disabled:opacity-50 text-white rounded px-2 py-1"
                  >
                    Load
                  </button>
                  <button
                    onClick={() => { setMessage(null); deleteMut.mutate(preset.name) }}
                    className="text-xs bg-red-600 hover:bg-red-700 text-white rounded px-2 py-1"
                  >
                    Delete
                  </button>
                </div>
              </div>
              {preset.description && (
                <p className="text-xs italic text-gray-400 dark:text-gray-500">{preset.description}</p>
              )}
              {expanded === preset.name && presetDetail && (
                <PresetDetail data={presetDetail} />
              )}
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}

function PresetDetail({ data }: { data: Record<string, unknown> }) {
  const state = (data.state ?? {}) as Record<string, unknown>
  const { prompt, negative_prompt, seed, ...otherOverrides } = state
  const hasOther = Object.keys(otherOverrides).length > 0

  return (
    <div className="mt-2 space-y-2 text-xs">
      {prompt != null && (
        <div>
          <span className="font-semibold text-gray-600 dark:text-gray-400">Prompt</span>
          <p className="mt-0.5 bg-gray-50 dark:bg-gray-800 rounded p-2 text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
            {String(prompt)}
          </p>
        </div>
      )}
      {negative_prompt != null && (
        <div>
          <span className="font-semibold text-gray-600 dark:text-gray-400">Negative prompt</span>
          <p className="mt-0.5 bg-gray-50 dark:bg-gray-800 rounded p-2 text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
            {String(negative_prompt)}
          </p>
        </div>
      )}
      {seed != null && (
        <div className="flex gap-2 items-baseline">
          <span className="font-semibold text-gray-600 dark:text-gray-400">Seed</span>
          <span className="font-mono text-gray-700 dark:text-gray-300">
            {String(seed)}
            {seed === -1 && <span className="ml-1 text-gray-400">(random)</span>}
          </span>
        </div>
      )}
      {hasOther && (
        <div>
          <span className="font-semibold text-gray-600 dark:text-gray-400">Other overrides</span>
          <table className="mt-0.5 w-full text-xs border-collapse">
            <tbody>
              {Object.entries(otherOverrides).map(([k, v]) => (
                <tr key={k} className="border-b border-gray-100 dark:border-gray-700">
                  <td className="py-0.5 pr-3 font-mono text-gray-500 dark:text-gray-400 whitespace-nowrap">{k}</td>
                  <td className="py-0.5 text-gray-700 dark:text-gray-300 break-all">{JSON.stringify(v)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
      {!!data.workflow && (
        <div className="text-green-600 dark:text-green-400">Includes workflow template</div>
      )}
      <details>
        <summary className="cursor-pointer text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">Raw JSON</summary>
        <pre className="mt-1 text-xs bg-gray-100 dark:bg-gray-800 rounded p-2 overflow-auto max-h-48 text-gray-600 dark:text-gray-400">
          {JSON.stringify(data, null, 2)}
        </pre>
      </details>
    </div>
  )
}
