import { useEffect, useState } from 'react'
import {
  apiRequest,
  listBackupPlans,
  createBackupPlan,
  updateBackupPlan,
  deleteBackupPlan,
  runScheduledBackups,
} from '../api/client'
import { Plus, Trash2, Play, Pencil } from 'lucide-react'

interface BackupPlanRecord {
  id: number
  name: string
  plan_type: string
  target_id: number
  schedule: string
  enabled: boolean
}

interface SiteRecord {
  id: number
  name: string
}

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

export function BackupPlansPage() {
  const [plans, setPlans] = useState<BackupPlanRecord[]>([])
  const [sites, setSites] = useState<SiteRecord[]>([])
  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 [editPlan, setEditPlan] = useState<BackupPlanRecord | null>(null)
  const [editPlanType, setEditPlanType] = useState<'site' | 'database'>('site')
  const [runLoading, setRunLoading] = useState(false)
  const [runResults, setRunResults] = useState<{ plan: string; status: string; msg?: string }[] | null>(null)
  const [createPlanType, setCreatePlanType] = useState<'site' | 'database'>('site')

  const loadPlans = () => {
    listBackupPlans()
      .then(setPlans)
      .catch((err) => setError(err.message))
  }

  useEffect(() => {
    setLoading(true)
    Promise.all([
      listBackupPlans(),
      apiRequest<SiteRecord[]>('/site/list'),
      apiRequest<DbRecord[]>('/database/list'),
    ])
      .then(([p, s, d]) => {
        setPlans(p)
        setSites(s)
        setDatabases(d.filter((x) => ['MySQL', 'PostgreSQL', 'MongoDB'].includes(x.db_type)))
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false))
  }, [])

  const handleCreate = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    const form = e.currentTarget
    const name = (form.elements.namedItem('name') as HTMLInputElement).value.trim()
    const plan_type = (form.elements.namedItem('plan_type') as HTMLSelectElement).value as 'site' | 'database'
    const target_id = Number((form.elements.namedItem('target_id') as HTMLSelectElement).value)
    const schedule = (form.elements.namedItem('schedule') as HTMLInputElement).value.trim()
    const enabled = (form.elements.namedItem('enabled') as HTMLInputElement).checked

    if (!name || !schedule || !target_id) {
      setError('Name, target and schedule are required')
      return
    }
    setCreating(true)
    createBackupPlan({ name, plan_type, target_id, schedule, enabled })
      .then(() => {
        setShowCreate(false)
        form.reset()
        loadPlans()
      })
      .catch((err) => setError(err.message))
      .finally(() => setCreating(false))
  }

  const handleDelete = (id: number, name: string) => {
    if (!confirm(`Delete backup plan "${name}"?`)) return
    deleteBackupPlan(id)
      .then(loadPlans)
      .catch((err) => setError(err.message))
  }

  const handleEdit = (plan: BackupPlanRecord) => {
    setEditPlan(plan)
    setEditPlanType(plan.plan_type as 'site' | 'database')
  }

  const handleUpdate = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    if (!editPlan) return
    const form = e.currentTarget
    const name = (form.elements.namedItem('edit_name') as HTMLInputElement).value.trim()
    const target_id = Number((form.elements.namedItem('edit_target_id') as HTMLSelectElement).value)
    const schedule = (form.elements.namedItem('edit_schedule') as HTMLInputElement).value.trim()
    const enabled = (form.elements.namedItem('edit_enabled') as HTMLInputElement).checked

    if (!name || !schedule || !target_id) return
    updateBackupPlan(editPlan.id, { name, plan_type: editPlanType, target_id, schedule, enabled })
      .then(() => {
        setEditPlan(null)
        loadPlans()
      })
      .catch((err) => setError(err.message))
  }

  const handleRunScheduled = () => {
    setRunLoading(true)
    setRunResults(null)
    runScheduledBackups()
      .then((r) => setRunResults(r.results))
      .catch((err) => setError(err.message))
      .finally(() => setRunLoading(false))
  }

  const getTargetName = (plan: BackupPlanRecord) => {
    if (plan.plan_type === 'site') {
      const s = sites.find((x) => x.id === plan.target_id)
      return s ? s.name : `#${plan.target_id}`
    }
    const d = databases.find((x) => x.id === plan.target_id)
    return d ? d.name : `#${plan.target_id}`
  }

  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">Backup Plans</h1>
        <div className="flex gap-2">
          <button
            onClick={handleRunScheduled}
            disabled={runLoading}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg disabled:opacity-50"
          >
            <Play className="w-4 h-4" />
            {runLoading ? 'Running...' : 'Run Scheduled'}
          </button>
          <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 Plan
          </button>
        </div>
      </div>

      {runResults && runResults.length > 0 && (
        <div className="mb-4 p-4 rounded bg-gray-100 dark:bg-gray-700">
          <h3 className="font-medium mb-2">Last run results</h3>
          <ul className="space-y-1 text-sm">
            {runResults.map((r, i) => (
              <li key={i}>
                {r.plan}: {r.status === 'ok' ? '✓' : r.status === 'skipped' ? '⊘' : '✗'} {r.msg || ''}
              </li>
            ))}
          </ul>
        </div>
      )}

      <p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
        Schedule automated backups. Add a cron entry (e.g. <code className="bg-gray-200 dark:bg-gray-700 px-1 rounded">0 * * * *</code> hourly) to call{' '}
        <code className="bg-gray-200 dark:bg-gray-700 px-1 rounded">POST /api/v1/backup/run-scheduled</code> with your auth token.
      </p>

      <div className="bg-white dark:bg-gray-800 rounded-lg 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">Type</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Target</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Schedule</th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">Enabled</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">
            {plans.length === 0 ? (
              <tr>
                <td colSpan={6} className="px-4 py-8 text-center text-gray-500">
                  No backup plans. Click "Add Plan" to create one.
                </td>
              </tr>
            ) : (
              plans.map((p) => (
                <tr key={p.id}>
                  <td className="px-4 py-2 text-gray-900 dark:text-white">{p.name}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{p.plan_type}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{getTargetName(p)}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400 font-mono text-sm">{p.schedule}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{p.enabled ? 'Yes' : 'No'}</td>
                  <td className="px-4 py-2 text-right">
                    <span className="flex gap-1 justify-end">
                      <button
                        onClick={() => handleEdit(p)}
                        className="p-2 text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded"
                        title="Edit"
                      >
                        <Pencil className="w-4 h-4" />
                      </button>
                      <button
                        onClick={() => handleDelete(p.id, p.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>

      {editPlan && (
        <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">Edit Backup Plan</h2>
            <form onSubmit={handleUpdate} className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label>
                <input
                  name="edit_name"
                  type="text"
                  defaultValue={editPlan.name}
                  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
                  value={editPlanType}
                  onChange={(e) => setEditPlanType(e.target.value as 'site' | 'database')}
                  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="site">Site</option>
                  <option value="database">Database</option>
                </select>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Target</label>
                <select
                  name="edit_target_id"
                  defaultValue={
                    editPlanType === editPlan.plan_type
                      ? editPlan.target_id
                      : editPlanType === 'site'
                        ? sites[0]?.id
                        : databases[0]?.id
                  }
                  key={editPlanType}
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                >
                  {editPlanType === 'site'
                    ? sites.map((s) => (
                        <option key={`s-${s.id}`} value={s.id}>
                          {s.name}
                        </option>
                      ))
                    : databases.map((d) => (
                        <option key={`d-${d.id}`} value={d.id}>
                          {d.name} ({d.db_type})
                        </option>
                      ))}
                </select>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Schedule (cron)</label>
                <input
                  name="edit_schedule"
                  type="text"
                  defaultValue={editPlan.schedule}
                  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 className="flex items-center gap-2">
                <input name="edit_enabled" type="checkbox" defaultChecked={editPlan.enabled} className="rounded" />
                <label className="text-sm text-gray-700 dark:text-gray-300">Enabled</label>
              </div>
              <div className="flex gap-2 justify-end pt-2">
                <button type="button" onClick={() => setEditPlan(null)} className="px-4 py-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
                  Cancel
                </button>
                <button type="submit" className="px-4 py-2 bg-blue-600 text-white rounded-lg">
                  Update
                </button>
              </div>
            </form>
          </div>
        </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">Add Backup Plan</h2>
            <form onSubmit={handleCreate} className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name</label>
                <input
                  name="name"
                  type="text"
                  placeholder="Daily site backup"
                  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="plan_type"
                  value={createPlanType}
                  onChange={(e) => setCreatePlanType(e.target.value as 'site' | 'database')}
                  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="site">Site</option>
                  <option value="database">Database</option>
                </select>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Target</label>
                <select
                  name="target_id"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                >
                  <option value="">Select...</option>
                  {createPlanType === 'site'
                    ? sites.map((s) => (
                        <option key={`s-${s.id}`} value={s.id}>
                          {s.name}
                        </option>
                      ))
                    : databases.map((d) => (
                        <option key={`d-${d.id}`} value={d.id}>
                          {d.name} ({d.db_type})
                        </option>
                      ))}
                </select>
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Schedule (cron)</label>
                <input
                  name="schedule"
                  type="text"
                  placeholder="0 2 * * *"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                />
                <p className="text-xs text-gray-500 mt-1">e.g. 0 2 * * * = daily at 2am, 0 */6 * * * = every 6 hours</p>
              </div>
              <div className="flex items-center gap-2">
                <input name="enabled" type="checkbox" defaultChecked className="rounded" />
                <label className="text-sm text-gray-700 dark:text-gray-300">Enabled</label>
              </div>
              <div className="flex gap-2 justify-end pt-2">
                <button type="button" onClick={() => setShowCreate(false)} className="px-4 py-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
                  Cancel
                </button>
                <button type="submit" disabled={creating} className="px-4 py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50">
                  {creating ? 'Creating...' : 'Create'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  )
}
