import { useEffect, useState } from 'react'
import {
  apiRequest,
  createDatabaseBackup,
  listDatabaseBackups,
  restoreDatabaseBackup,
  downloadDatabaseBackup,
  updateDatabasePassword,
} from '../api/client'
import { Plus, Trash2, Archive, Download, RotateCcw, Key } from 'lucide-react'

interface DbRecord {
  id: number
  name: string
  username: string
  db_type: string
  ps: string
}

export function DatabasePage() {
  const [databases, setDatabases] = useState<DbRecord[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [showCreate, setShowCreate] = useState(false)
  const [creating, setCreating] = useState(false)
  const [creatingError, setCreatingError] = useState('')
  const [backupDbId, setBackupDbId] = useState<number | null>(null)
  const [backups, setBackups] = useState<{ filename: string; size: number }[]>([])
  const [backupLoading, setBackupLoading] = useState(false)
  const [changePwId, setChangePwId] = useState<number | null>(null)
  const [pwError, setPwError] = useState('')

  const loadDatabases = () => {
    setLoading(true)
    apiRequest<DbRecord[]>('/database/list')
      .then(setDatabases)
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    loadDatabases()
  }, [])

  const handleCreate = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    const form = e.currentTarget
    const name = (form.elements.namedItem('name') as HTMLInputElement).value.trim()
    const username = (form.elements.namedItem('username') as HTMLInputElement).value.trim()
    const password = (form.elements.namedItem('password') as HTMLInputElement).value
    const db_type = (form.elements.namedItem('db_type') as HTMLSelectElement).value
    const ps = (form.elements.namedItem('ps') as HTMLInputElement).value.trim()

    if (!name || !username || !password) {
      setCreatingError('Name, username and password are required')
      return
    }
    setCreating(true)
    setCreatingError('')
    apiRequest<{ status: boolean; msg: string }>('/database/create', {
      method: 'POST',
      body: JSON.stringify({ name, username, password, db_type, ps }),
    })
      .then(() => {
        setShowCreate(false)
        form.reset()
        loadDatabases()
      })
      .catch((err) => setCreatingError(err.message))
      .finally(() => setCreating(false))
  }

  const handleDelete = (id: number, name: string) => {
    if (!confirm(`Delete database "${name}"?`)) return
    apiRequest<{ status: boolean }>(`/database/${id}`, { method: 'DELETE' })
      .then(loadDatabases)
      .catch((err) => setError(err.message))
  }

  const openBackupModal = (dbId: number) => {
    setBackupDbId(dbId)
    setBackups([])
    listDatabaseBackups(dbId)
      .then((data) => setBackups(data.backups || []))
      .catch((err) => setError(err.message))
  }

  const handleCreateBackup = () => {
    if (!backupDbId) return
    setBackupLoading(true)
    createDatabaseBackup(backupDbId)
      .then(() => listDatabaseBackups(backupDbId!).then((d) => setBackups(d.backups || [])))
      .catch((err) => setError(err.message))
      .finally(() => setBackupLoading(false))
  }

  const handleRestore = (filename: string) => {
    if (!backupDbId || !confirm(`Restore from ${filename}? This will overwrite the database.`)) return
    setBackupLoading(true)
    restoreDatabaseBackup(backupDbId, filename)
      .then(() => setBackupDbId(null))
      .catch((err) => setError(err.message))
      .finally(() => setBackupLoading(false))
  }

  const handleDownloadBackup = (filename: string) => {
    if (!backupDbId) return
    downloadDatabaseBackup(backupDbId, filename).catch((err) => setError(err.message))
  }

  const handleChangePassword = (e: React.FormEvent, id: number) => {
    e.preventDefault()
    const form = e.currentTarget
    const password = (form.elements.namedItem('new_password') as HTMLInputElement).value
    const confirm = (form.elements.namedItem('confirm_password') as HTMLInputElement).value
    if (!password || password.length < 6) {
      setPwError('Password must be at least 6 characters')
      return
    }
    if (password !== confirm) {
      setPwError('Passwords do not match')
      return
    }
    setPwError('')
    updateDatabasePassword(id, password)
      .then(() => setChangePwId(null))
      .catch((err) => setPwError(err.message))
  }

  const formatSize = (bytes: number) => {
    if (bytes < 1024) return bytes + ' B'
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
    return (bytes / 1024 / 1024).toFixed(1) + ' MB'
  }

  if (loading) return <div className="text-gray-500">Loading...</div>
  if (error) return <div className="p-4 rounded bg-red-100 text-red-700">{error}</div>

  return (
    <div>
      <div className="flex justify-between items-center mb-4">
        <h1 className="text-2xl font-bold text-gray-800 dark:text-white">Databases</h1>
        <button
          onClick={() => setShowCreate(true)}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium"
        >
          <Plus className="w-4 h-4" />
          Add Database
        </button>
      </div>

      {showCreate && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md">
            <h2 className="text-xl font-bold mb-4 text-gray-800 dark:text-white">Create Database</h2>
            <form onSubmit={handleCreate} className="space-y-4">
              {creatingError && (
                <div className="p-2 rounded bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 text-sm">
                  {creatingError}
                </div>
              )}
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Database Name</label>
                <input
                  name="name"
                  type="text"
                  placeholder="mydb"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Username</label>
                <input
                  name="username"
                  type="text"
                  placeholder="dbuser"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Password</label>
                <input
                  name="password"
                  type="password"
                  placeholder="••••••••"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Type</label>
                <select
                  name="db_type"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                >
                  <option value="MySQL">MySQL (full support)</option>
                  <option value="PostgreSQL">PostgreSQL (full support)</option>
                  <option value="MongoDB">MongoDB (full support)</option>
                  <option value="Redis">Redis (panel record only)</option>
                </select>
                <p className="mt-1 text-xs text-gray-500">MySQL, PostgreSQL, MongoDB: create, delete, backup/restore. MySQL/PostgreSQL/MongoDB: password change.</p>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Note (optional)</label>
                <input
                  name="ps"
                  type="text"
                  placeholder="My database"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                />
              </div>
              <div className="flex gap-2 justify-end pt-2">
                <button
                  type="button"
                  onClick={() => setShowCreate(false)}
                  className="px-4 py-2 text-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg"
                >
                  Cancel
                </button>
                <button
                  type="submit"
                  disabled={creating}
                  className="px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white rounded-lg font-medium"
                >
                  {creating ? 'Creating...' : 'Create'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      <div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
          <thead className="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Name</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Username</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Type</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Note</th>
              <th className="px-4 py-2 text-right text-sm font-medium text-gray-700 dark:text-gray-300">Actions</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 dark:divide-gray-700">
            {databases.length === 0 ? (
              <tr>
                <td colSpan={5} className="px-4 py-8 text-center text-gray-500">
                  No databases. Click "Add Database" to create one.
                </td>
              </tr>
            ) : (
              databases.map((d) => (
                <tr key={d.id}>
                  <td className="px-4 py-2 text-gray-900 dark:text-white">{d.name}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{d.username}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{d.db_type}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{d.ps || '-'}</td>
                  <td className="px-4 py-2 text-right">
                    <span className="flex gap-1 justify-end">
                      {(d.db_type === 'MySQL' || d.db_type === 'PostgreSQL' || d.db_type === 'MongoDB') && (
                        <button
                          onClick={() => openBackupModal(d.id)}
                          className="p-2 text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded"
                          title="Backup"
                        >
                          <Archive className="w-4 h-4" />
                        </button>
                      )}
                      {(d.db_type === 'MySQL' || d.db_type === 'PostgreSQL' || d.db_type === 'MongoDB') && (
                        <button
                          onClick={() => setChangePwId(d.id)}
                          className="p-2 text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-900/20 rounded"
                          title="Change password"
                        >
                          <Key className="w-4 h-4" />
                        </button>
                      )}
                      <button
                        onClick={() => handleDelete(d.id, d.name)}
                        className="p-2 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded"
                        title="Delete"
                      >
                        <Trash2 className="w-4 h-4" />
                      </button>
                    </span>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>

      {backupDbId && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-lg">
            <h2 className="text-xl font-bold mb-4 text-gray-800 dark:text-white">Database Backup</h2>
            <div className="mb-4">
              <button
                onClick={handleCreateBackup}
                disabled={backupLoading}
                className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg disabled:opacity-50"
              >
                <Archive className="w-4 h-4" />
                {backupLoading ? 'Creating...' : 'Create Backup'}
              </button>
            </div>
            <div className="mb-4">
              <h3 className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Existing backups</h3>
              {backups.length === 0 ? (
                <p className="text-gray-500 text-sm">No backups yet</p>
              ) : (
                <ul className="space-y-2 max-h-48 overflow-y-auto">
                  {backups.map((b) => (
                    <li key={b.filename} className="flex items-center justify-between gap-2 text-sm">
                      <span className="truncate font-mono text-gray-700 dark:text-gray-300 flex-1">
                        {b.filename}
                      </span>
                      <span className="text-gray-500 text-xs flex-shrink-0">{formatSize(b.size)}</span>
                      <span className="flex gap-1 flex-shrink-0">
                        <button
                          onClick={() => handleDownloadBackup(b.filename)}
                          className="p-1.5 text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded"
                          title="Download"
                        >
                          <Download className="w-4 h-4" />
                        </button>
                        <button
                          onClick={() => handleRestore(b.filename)}
                          disabled={backupLoading}
                          className="p-1.5 text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-900/20 rounded disabled:opacity-50"
                          title="Restore"
                        >
                          <RotateCcw className="w-4 h-4" />
                        </button>
                      </span>
                    </li>
                  ))}
                </ul>
              )}
            </div>
            <div className="flex justify-end">
              <button
                onClick={() => setBackupDbId(null)}
                className="px-4 py-2 text-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg"
              >
                Close
              </button>
            </div>
          </div>
        </div>
      )}

      {changePwId && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md">
            <h2 className="text-xl font-bold mb-4 text-gray-800 dark:text-white">Change Database Password</h2>
            <form onSubmit={(e) => handleChangePassword(e, changePwId)} className="space-y-4">
              {pwError && (
                <div className="p-2 rounded bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300 text-sm">
                  {pwError}
                </div>
              )}
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">New Password</label>
                <input name="new_password" type="password" minLength={6} className="w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700" required />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Confirm Password</label>
                <input name="confirm_password" type="password" minLength={6} className="w-full px-4 py-2 border rounded-lg bg-white dark:bg-gray-700" required />
              </div>
              <div className="flex gap-2 justify-end">
                <button type="button" onClick={() => setChangePwId(null)} className="px-4 py-2 text-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
                  Cancel
                </button>
                <button type="submit" className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">
                  Update
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  )
}
