import React, { useState } from 'react'
import { EmptyState, Sub } from '../../primitives'
import { AuthError, APIError } from '../../api/client'
import type { SavedSearch } from '../../api/adapters'
import {
  useSavedSearches,
  useCreateSavedSearch,
  useUpdateSavedSearch,
  useDeleteSavedSearch,
} from './useSavedSearches'

// ── Inline "Add new" form ─────────────────────────────────────────────────────

function AddForm(): React.JSX.Element {
  const [name, setName] = useState('')
  const [query, setQuery] = useState('')
  const createMutation = useCreateSavedSearch()

  function handleSave(e: React.FormEvent) {
    e.preventDefault()
    if (!name.trim() || !query.trim()) return
    createMutation.mutate(
      { name: name.trim(), query: query.trim() },
      {
        onSuccess: () => {
          setName('')
          setQuery('')
        },
      },
    )
  }

  return (
    <form className="saved-search-form" onSubmit={handleSave}>
      <input
        className="saved-search-input"
        placeholder="name"
        value={name}
        onChange={(e) => setName(e.target.value)}
        autoComplete="off"
      />
      <input
        className="saved-search-input saved-search-input-mono"
        placeholder="query"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        autoComplete="off"
      />
      <button
        className="saved-search-btn"
        type="submit"
        disabled={createMutation.isPending}
      >
        save
      </button>
      {createMutation.isError && (
        <span className="saved-search-error">
          {createMutation.error instanceof APIError
            ? createMutation.error.message
            : String(createMutation.error)}
        </span>
      )}
    </form>
  )
}

// ── Per-row inline edit form ──────────────────────────────────────────────────

interface RowProps {
  row: SavedSearch
}

function SavedSearchRow({ row }: RowProps): React.JSX.Element {
  const [editing, setEditing] = useState(false)
  const [name, setName] = useState(row.name)
  const [query, setQuery] = useState(row.query)
  const updateMutation = useUpdateSavedSearch()
  const deleteMutation = useDeleteSavedSearch()

  function handleSave(e: React.FormEvent) {
    e.preventDefault()
    updateMutation.mutate(
      { oldName: row.name, name: name.trim() || undefined, query: query.trim() || undefined },
      { onSuccess: () => setEditing(false) },
    )
  }

  function handleDelete() {
    deleteMutation.mutate({ name: row.name })
  }

  if (editing) {
    return (
      <div className="saved-searches-row saved-searches-row-editing">
        <form className="saved-search-form" onSubmit={handleSave}>
          <input
            className="saved-search-input"
            value={name}
            onChange={(e) => setName(e.target.value)}
            autoComplete="off"
          />
          <input
            className="saved-search-input saved-search-input-mono"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            autoComplete="off"
          />
          <button className="saved-search-btn" type="submit" disabled={updateMutation.isPending}>
            save
          </button>
          <button
            className="saved-search-btn"
            type="button"
            onClick={() => {
              setEditing(false)
              setName(row.name)
              setQuery(row.query)
            }}
          >
            cancel
          </button>
        </form>
        {updateMutation.isError && (
          <span className="saved-search-error">
            {updateMutation.error instanceof APIError
              ? updateMutation.error.message
              : String(updateMutation.error)}
          </span>
        )}
      </div>
    )
  }

  return (
    <div className="saved-searches-row">
      <span className="saved-searches-cell saved-searches-name">{row.name}</span>
      <span className="saved-searches-cell saved-searches-query mono">{row.query}</span>
      <span className="saved-searches-cell saved-searches-updated muted">
        {new Date(row.updatedAt).toLocaleDateString()}
      </span>
      <span className="saved-searches-cell saved-searches-actions">
        <button
          className="saved-search-btn"
          type="button"
          onClick={() => setEditing(true)}
        >
          edit
        </button>
        <button
          className="saved-search-btn saved-search-btn-danger"
          type="button"
          onClick={handleDelete}
          disabled={deleteMutation.isPending}
        >
          delete
        </button>
      </span>
      {deleteMutation.isError && (
        <span className="saved-search-error">
          {deleteMutation.error instanceof APIError
            ? deleteMutation.error.message
            : String(deleteMutation.error)}
        </span>
      )}
    </div>
  )
}

// ── Main section ──────────────────────────────────────────────────────────────

export function SavedSearchesSection(): React.JSX.Element {
  const { data, isLoading, error } = useSavedSearches()

  if (isLoading) {
    return <Sub>loading…</Sub>
  }

  if (error != null) {
    if (error instanceof AuthError) {
      return (
        <div
          className="body body-pad"
          style={{ display: 'flex', justifyContent: 'center', paddingTop: 60 }}
        >
          <div className="card" style={{ padding: '24px 32px', textAlign: 'center' }}>
            <div className="uppercase-mono" style={{ marginBottom: 8 }}>not authenticated</div>
            <div className="muted">Sign in to manage your saved searches.</div>
          </div>
        </div>
      )
    }
    const detail = error instanceof APIError ? error.message : String(error)
    return (
      <div
        className="body body-pad"
        style={{ display: 'flex', justifyContent: 'center', paddingTop: 60 }}
      >
        <div className="card" style={{ padding: '24px 32px', textAlign: 'center' }}>
          <div className="uppercase-mono" style={{ marginBottom: 8 }}>error</div>
          <div className="muted">{detail}</div>
        </div>
      </div>
    )
  }

  return (
    <div className="saved-searches-section">
      <div className="saved-searches-heading">Saved searches</div>
      <AddForm />
      {data != null && data.length === 0 ? (
        <EmptyState glyph="∅" copy="no saved searches yet" />
      ) : (
        <div className="saved-searches-table">
          <div className="saved-searches-thead">
            <span>Name</span>
            <span>Query</span>
            <span>Updated</span>
            <span></span>
          </div>
          {data?.map((row) => (
            <SavedSearchRow key={row.name} row={row} />
          ))}
        </div>
      )}
    </div>
  )
}
