import { useState, useRef } from 'react'
import { api } from '../api'

export default function Remap() {
  const [search, setSearch] = useState('')
  const [results, setResults] = useState(null)
  const [searching, setSearching] = useState(false)

  const [selected, setSelected] = useState(null)   // { col, val }
  const [matches, setMatches] = useState(null)      // individual mappings
  const [loadingMatches, setLoadingMatches] = useState(false)

  const [toVal, setToVal] = useState('')
  const [applying, setApplying] = useState(false)
  const [msg, setMsg] = useState(null)              // { text, ok }

  const searchRef = useRef()

  async function handleSearch(e) {
    e.preventDefault()
    const q = search.trim()
    if (!q) return
    setSearching(true)
    setResults(null)
    setSelected(null)
    setMatches(null)
    setMsg(null)
    try {
      const rows = await api.searchMappingOutputs(q)
      setResults(rows)
    } catch (err) {
      setMsg({ text: err.message, ok: false })
    } finally {
      setSearching(false)
    }
  }

  async function handleSelect(row) {
    setSelected(row)
    setToVal(row.val)
    setMatches(null)
    setMsg(null)
    setLoadingMatches(true)
    try {
      const rows = await api.getMappingsByOutputField(row.col, row.val)
      setMatches(rows)
    } catch (err) {
      setMsg({ text: err.message, ok: false })
    } finally {
      setLoadingMatches(false)
    }
  }

  async function handleApply() {
    if (!selected || !toVal.trim() || toVal === selected.val) return
    setApplying(true)
    setMsg(null)
    try {
      const { updated } = await api.remapOutputField(selected.col, selected.val, toVal.trim())
      setMsg({ text: `Updated ${updated} mapping${updated !== 1 ? 's' : ''}.`, ok: true })
      // Refresh match list to show new values
      const rows = await api.getMappingsByOutputField(selected.col, toVal.trim())
      setMatches(rows)
      setSelected({ ...selected, val: toVal.trim() })
      // Re-run search to refresh counts
      const refreshed = await api.searchMappingOutputs(search.trim())
      setResults(refreshed)
    } catch (err) {
      setMsg({ text: err.message, ok: false })
    } finally {
      setApplying(false)
    }
  }

  return (
    <div className="p-6 max-w-4xl">
      <h1 className="text-base font-semibold text-gray-800 mb-4">Remap Output Values</h1>

      {/* Search */}
      <form onSubmit={handleSearch} className="flex items-center gap-2 mb-5">
        <input
          ref={searchRef}
          value={search}
          onChange={e => setSearch(e.target.value)}
          placeholder="Search output values…"
          className="text-sm border border-gray-300 rounded px-3 py-1.5 w-72 focus:outline-none focus:border-blue-400"
        />
        <button type="submit" disabled={searching}
          className="text-sm bg-blue-600 text-white rounded px-3 py-1.5 hover:bg-blue-700 disabled:opacity-50">
          {searching ? 'Searching…' : 'Search'}
        </button>
      </form>

      {/* Search results */}
      {results !== null && (
        <div className="mb-6">
          {results.length === 0 ? (
            <p className="text-sm text-gray-400">No matching output values found.</p>
          ) : (
            <>
              <div className="text-xs text-gray-400 uppercase tracking-wide mb-1">
                {results.length} result{results.length !== 1 ? 's' : ''} — click one to remap
              </div>
              <table className="w-full text-sm border border-gray-200 rounded overflow-hidden">
                <thead>
                  <tr className="bg-gray-50 text-left text-xs text-gray-400 uppercase tracking-wide">
                    <th className="px-3 py-2">Field</th>
                    <th className="px-3 py-2">Value</th>
                    <th className="px-3 py-2 text-right">Mappings</th>
                  </tr>
                </thead>
                <tbody>
                  {results.map((r, i) => {
                    const isActive = selected?.col === r.col && selected?.val === r.val
                    return (
                      <tr key={i}
                        onClick={() => handleSelect(r)}
                        className={`border-t border-gray-100 cursor-pointer transition-colors
                          ${isActive ? 'bg-blue-50' : 'hover:bg-gray-50'}`}>
                        <td className="px-3 py-2 font-mono text-gray-500">{r.col}</td>
                        <td className="px-3 py-2 font-mono text-gray-800">{r.val}</td>
                        <td className="px-3 py-2 text-right text-gray-400">{r.mapping_count}</td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </>
          )}
        </div>
      )}

      {/* Remap panel */}
      {selected && (
        <div className="border border-gray-200 rounded p-4 mb-6 bg-white">
          <div className="text-xs text-gray-400 uppercase tracking-wide mb-3">
            Remap <span className="font-mono text-gray-600">{selected.col}</span>
          </div>
          <div className="flex items-center gap-3 mb-4">
            <div className="flex-1">
              <div className="text-xs text-gray-400 mb-1">From</div>
              <div className="text-sm font-mono bg-gray-50 border border-gray-200 rounded px-3 py-1.5 text-gray-700">
                {selected.val}
              </div>
            </div>
            <div className="text-gray-300 mt-4">→</div>
            <div className="flex-1">
              <div className="text-xs text-gray-400 mb-1">To</div>
              <input
                value={toVal}
                onChange={e => setToVal(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && handleApply()}
                className="w-full text-sm font-mono border border-gray-300 rounded px-3 py-1.5 focus:outline-none focus:border-blue-400"
              />
            </div>
            <div className="mt-4">
              <button
                onClick={handleApply}
                disabled={applying || !toVal.trim() || toVal.trim() === selected.val}
                className="text-sm bg-blue-600 text-white rounded px-3 py-1.5 hover:bg-blue-700 disabled:opacity-40 whitespace-nowrap">
                {applying ? 'Applying…' : `Apply to all ${matches?.length ?? '…'}`}
              </button>
            </div>
          </div>

          {msg && (
            <div className={`text-sm mb-3 ${msg.ok ? 'text-green-600' : 'text-red-500'}`}>
              {msg.text}
            </div>
          )}

          {/* Affected mappings */}
          {loadingMatches ? (
            <p className="text-xs text-gray-400">Loading…</p>
          ) : matches && matches.length > 0 && (
            <div>
              <div className="text-xs text-gray-400 uppercase tracking-wide mb-1">
                Affected mappings
              </div>
              <table className="w-full text-xs border border-gray-100 rounded overflow-hidden">
                <thead>
                  <tr className="bg-gray-50 text-left text-gray-400">
                    <th className="px-2 py-1">Source</th>
                    <th className="px-2 py-1">Rule</th>
                    <th className="px-2 py-1">Input</th>
                    <th className="px-2 py-1">Output</th>
                  </tr>
                </thead>
                <tbody>
                  {matches.map(m => (
                    <tr key={m.id} className="border-t border-gray-50">
                      <td className="px-2 py-1 font-mono text-gray-500">{m.source_name}</td>
                      <td className="px-2 py-1 font-mono text-gray-500">{m.rule_name}</td>
                      <td className="px-2 py-1 font-mono text-gray-700">
                        {typeof m.input_value === 'string' ? m.input_value : JSON.stringify(m.input_value)}
                      </td>
                      <td className="px-2 py-1 font-mono text-gray-700">
                        {Object.entries(m.output).map(([k, v]) => (
                          <span key={k} className={k === selected.col ? 'text-blue-600 font-semibold' : ''}>
                            {k}: {v}{' '}
                          </span>
                        ))}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}
    </div>
  )
}
