'use client'

import { useCallback, useEffect, useRef, useState } from 'react'
import { ADMIN_API_BASE } from '@/lib/api'

type ContainerStatus = 'PENDING' | 'CREATING' | 'RUNNING' | 'STOPPED' | 'RESTARTING' | 'REMOVING' | 'ERROR'

interface CompanyContainer {
  id: string
  companyId: string
  dockerId: string | null
  containerName: string
  status: ContainerStatus
  port: number
  image: string
  errorMessage: string | null
  createdAt: string
  updatedAt: string
  company: {
    id: string
    name: string
    slug: string
    status: string
  }
}

function authHeaders() {
  return { 'Content-Type': 'application/json' }
}

function StatusBadge({ status }: { status: ContainerStatus }) {
  const map: Record<ContainerStatus, { label: string; className: string }> = {
    PENDING:    { label: 'Pending',    className: 'bg-zinc-700 text-zinc-300' },
    CREATING:   { label: 'Creating…',  className: 'bg-blue-900 text-blue-300 animate-pulse' },
    RUNNING:    { label: 'Running',    className: 'bg-emerald-900 text-emerald-300' },
    STOPPED:    { label: 'Stopped',    className: 'bg-orange-900 text-orange-300' },
    RESTARTING: { label: 'Restarting…',className: 'bg-orange-900 text-orange-300 animate-pulse' },
    REMOVING:   { label: 'Removing…',  className: 'bg-red-900 text-red-300 animate-pulse' },
    ERROR:      { label: 'Error',      className: 'bg-red-950 text-red-400' },
  }
  const { label, className } = map[status] ?? map.ERROR
  return (
    <span className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium ${className}`}>
      <span className={`h-1.5 w-1.5 rounded-full ${status === 'RUNNING' ? 'bg-emerald-400' : 'bg-current opacity-60'}`} />
      {label}
    </span>
  )
}

function LogsModal({ companyId, companyName, onClose }: { companyId: string; companyName: string; onClose: () => void }) {
  const [logs, setLogs] = useState<string>('')
  const [loading, setLoading] = useState(true)
  const [tail, setTail] = useState(150)
  const bottomRef = useRef<HTMLDivElement>(null)

  const fetchLogs = useCallback(async (lines: number) => {
    setLoading(true)
    try {
      const res = await fetch(`${ADMIN_API_BASE}/admin/containers/${companyId}/logs?tail=${lines}`, { headers: authHeaders(), credentials: 'include' })
      const json = await res.json()
      setLogs(json.data?.logs ?? '')
    } catch {
      setLogs('Failed to fetch logs.')
    } finally {
      setLoading(false)
    }
  }, [companyId])

  useEffect(() => { fetchLogs(tail) }, [fetchLogs, tail])
  useEffect(() => { bottomRef.current?.scrollIntoView() }, [logs])

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#07101e]/70 p-4" onClick={onClose}>
      <div className="flex h-[80vh] w-full max-w-4xl flex-col rounded-2xl border border-zinc-700 bg-zinc-900 shadow-2xl" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between border-b border-zinc-700 px-5 py-4">
          <div>
            <p className="text-sm font-semibold text-zinc-100">Container Logs</p>
            <p className="text-xs text-zinc-400">{companyName}</p>
          </div>
          <div className="flex items-center gap-3">
            <select
              value={tail}
              onChange={(e) => setTail(Number(e.target.value))}
              className="rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-1.5 text-xs text-zinc-200 focus:outline-none"
            >
              <option value={50}>Last 50 lines</option>
              <option value={150}>Last 150 lines</option>
              <option value={500}>Last 500 lines</option>
              <option value={1000}>Last 1000 lines</option>
            </select>
            <button onClick={() => fetchLogs(tail)} className="rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-1.5 text-xs text-zinc-300 hover:bg-zinc-700">
              Refresh
            </button>
            <button onClick={onClose} className="rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-1.5 text-xs text-zinc-300 hover:bg-zinc-700">
              Close
            </button>
          </div>
        </div>
        <div className="flex-1 overflow-y-auto p-4">
          {loading ? (
            <p className="text-xs text-zinc-500">Loading…</p>
          ) : (
            <pre className="whitespace-pre-wrap break-all font-mono text-xs leading-relaxed text-zinc-300">
              {logs || 'No logs available.'}
            </pre>
          )}
          <div ref={bottomRef} />
        </div>
      </div>
    </div>
  )
}

type ProvisionResult = { companyId: string; name: string; status: 'created' | 'error'; error?: string }

export default function ContainersPage() {
  const [containers, setContainers] = useState<CompanyContainer[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [busy, setBusy] = useState<Record<string, boolean>>({})
  const [logsFor, setLogsFor] = useState<{ companyId: string; companyName: string } | null>(null)
  const [search, setSearch] = useState('')
  const [provisioning, setProvisioning] = useState(false)
  const [provisionResults, setProvisionResults] = useState<ProvisionResult[] | null>(null)

  const fetchContainers = useCallback(async () => {
    try {
      const res = await fetch(`${ADMIN_API_BASE}/admin/containers`, { headers: authHeaders(), credentials: 'include' })
      const json = await res.json().catch(() => null)
      if (!res.ok) {
        throw new Error(json?.message ?? 'Failed to load containers.')
      }
      setContainers(json.data ?? [])
      setError(null)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load containers.')
      /* silent — keep old data */
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    fetchContainers()
    const id = setInterval(fetchContainers, 8000)
    return () => clearInterval(id)
  }, [fetchContainers])

  async function provisionAll() {
    setProvisioning(true)
    setProvisionResults(null)
    try {
      const res = await fetch(`${ADMIN_API_BASE}/admin/containers/provision-all`, { method: 'POST', headers: authHeaders(), credentials: 'include' })
      const json = await res.json().catch(() => null)
      if (!res.ok) throw new Error(json?.message ?? 'Provisioning failed.')
      setProvisionResults(json.data?.results ?? [])
      setError(null)
      await fetchContainers()
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Provisioning failed.')
    } finally {
      setProvisioning(false)
    }
  }

  async function act(companyId: string, action: 'start' | 'stop' | 'restart' | 'deploy' | 'remove') {
    setBusy((b) => ({ ...b, [companyId]: true }))
    try {
      const method = action === 'remove' ? 'DELETE' : 'POST'
      const url =
        action === 'remove'
          ? `${ADMIN_API_BASE}/admin/containers/${companyId}`
          : `${ADMIN_API_BASE}/admin/containers/${companyId}/${action}`
      const res = await fetch(url, { method, headers: authHeaders(), credentials: 'include' })
      const json = await res.json().catch(() => null)
      if (!res.ok) {
        throw new Error(json?.message ?? `Failed to ${action} container.`)
      }
      setError(null)
      await fetchContainers()
    } catch (err) {
      setError(err instanceof Error ? err.message : `Failed to ${action} container.`)
    } finally {
      setBusy((b) => ({ ...b, [companyId]: false }))
    }
  }

  const filtered = containers.filter(
    (c) =>
      c.company.name.toLowerCase().includes(search.toLowerCase()) ||
      c.containerName.toLowerCase().includes(search.toLowerCase()) ||
      c.company.slug.toLowerCase().includes(search.toLowerCase()),
  )

  const stats = {
    running: containers.filter((c) => c.status === 'RUNNING').length,
    stopped: containers.filter((c) => c.status === 'STOPPED').length,
    error: containers.filter((c) => c.status === 'ERROR').length,
    total: containers.length,
  }

  return (
    <div className="min-h-full p-8">
      {logsFor && (
        <LogsModal
          companyId={logsFor.companyId}
          companyName={logsFor.companyName}
          onClose={() => setLogsFor(null)}
        />
      )}

      <div className="mb-8 flex items-start justify-between">
        <div>
          <h1 className="text-xl font-semibold text-zinc-100">Containers</h1>
          <p className="mt-1 text-sm text-zinc-400">Manage isolated Docker Compose services for each company workspace.</p>
        </div>
        <button
          onClick={provisionAll}
          disabled={provisioning}
          className="flex items-center gap-2 rounded-xl bg-emerald-700 px-4 py-2 text-sm font-medium text-white hover:bg-emerald-600 disabled:cursor-not-allowed disabled:opacity-50 transition-colors"
        >
          {provisioning ? (
            <>
              <span className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
              Provisioning…
            </>
          ) : (
            <>
              <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.347a1.125 1.125 0 0 1 0 1.972l-11.54 6.347a1.125 1.125 0 0 1-1.667-.986V5.653Z" />
              </svg>
              Provision All Accounts
            </>
          )}
        </button>
      </div>

      {error && (
        <div className="mb-6 rounded-xl border border-red-900 bg-red-950/70 px-4 py-3 text-sm text-red-200">
          {error}
        </div>
      )}

      {provisionResults !== null && (
        <div className="mb-6 rounded-xl border border-zinc-800 bg-zinc-900 p-4">
          <div className="mb-3 flex items-center justify-between">
            <p className="text-sm font-medium text-zinc-200">
              Provisioning complete —{' '}
              <span className="text-emerald-400">{provisionResults.filter((r) => r.status === 'created').length} created</span>
              {provisionResults.some((r) => r.status === 'error') && (
                <>, <span className="text-red-400">{provisionResults.filter((r) => r.status === 'error').length} failed</span></>
              )}
            </p>
            <button onClick={() => setProvisionResults(null)} className="text-xs text-zinc-500 hover:text-zinc-300">Dismiss</button>
          </div>
          <div className="space-y-1.5 max-h-48 overflow-y-auto">
            {provisionResults.map((r) => (
              <div key={r.companyId} className="flex items-center gap-3 rounded-lg px-3 py-2 bg-zinc-800/60">
                <span className={`h-1.5 w-1.5 flex-shrink-0 rounded-full ${r.status === 'created' ? 'bg-emerald-400' : 'bg-red-400'}`} />
                <span className="text-sm text-zinc-300 flex-1">{r.name}</span>
                {r.status === 'error' && <span className="text-xs text-red-400 truncate max-w-xs">{r.error}</span>}
                {r.status === 'created' && <span className="text-xs text-emerald-500">Service created</span>}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Stats */}
      <div className="mb-6 grid grid-cols-4 gap-4">
        {[
          { label: 'Total', value: stats.total, color: 'text-zinc-100' },
          { label: 'Running', value: stats.running, color: 'text-emerald-400' },
          { label: 'Stopped', value: stats.stopped, color: 'text-orange-400' },
          { label: 'Error', value: stats.error, color: 'text-red-400' },
        ].map((s) => (
          <div key={s.label} className="rounded-xl border border-zinc-800 bg-zinc-900 p-4">
            <p className="text-xs text-zinc-500">{s.label}</p>
            <p className={`mt-1 text-2xl font-bold ${s.color}`}>{s.value}</p>
          </div>
        ))}
      </div>

      {/* Search */}
      <div className="mb-4">
        <input
          type="text"
          placeholder="Search by company name or container…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="w-full max-w-sm rounded-xl border border-zinc-700 bg-zinc-800 px-4 py-2 text-sm text-zinc-200 placeholder-zinc-500 focus:outline-none focus:ring-1 focus:ring-emerald-500"
        />
      </div>

      {/* Table */}
      <div className="overflow-hidden rounded-xl border border-zinc-800 bg-zinc-900">
        {loading ? (
          <div className="flex items-center justify-center py-16">
            <div className="h-6 w-6 animate-spin rounded-full border-2 border-emerald-500 border-t-transparent" />
          </div>
        ) : filtered.length === 0 ? (
          <div className="py-16 text-center text-sm text-zinc-500">
            {search ? 'No containers match your search.' : 'No containers yet. They are created automatically on company signup.'}
          </div>
        ) : (
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-zinc-800 text-left text-xs text-zinc-500">
                <th className="px-5 py-3 font-medium">Company</th>
                <th className="px-5 py-3 font-medium">Container</th>
                <th className="px-5 py-3 font-medium">Status</th>
                <th className="px-5 py-3 font-medium">Port</th>
                <th className="px-5 py-3 font-medium">Image</th>
                <th className="px-5 py-3 font-medium">Actions</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-zinc-800">
              {filtered.map((c) => {
                const isBusy = busy[c.companyId] ?? false
                const isRunning = c.status === 'RUNNING'
                const isStopped = c.status === 'STOPPED' || c.status === 'ERROR'
                const isTransitioning = ['CREATING', 'RESTARTING', 'REMOVING'].includes(c.status)

                return (
                  <tr key={c.id} className="hover:bg-zinc-800/40">
                    <td className="px-5 py-4">
                      <p className="font-medium text-zinc-100">{c.company.name}</p>
                      <p className="text-xs text-zinc-500">{c.company.slug}</p>
                      {c.errorMessage && (
                        <p className="mt-1 text-xs text-red-400" title={c.errorMessage}>
                          {c.errorMessage.slice(0, 60)}{c.errorMessage.length > 60 ? '…' : ''}
                        </p>
                      )}
                    </td>
                    <td className="px-5 py-4 font-mono text-xs text-zinc-400">
                      {c.containerName}
                      {c.dockerId && (
                        <p className="mt-0.5 text-zinc-600">{c.dockerId.slice(0, 12)}</p>
                      )}
                    </td>
                    <td className="px-5 py-4">
                      <StatusBadge status={c.status} />
                    </td>
                    <td className="px-5 py-4 font-mono text-xs text-zinc-400">:{c.port}</td>
                    <td className="px-5 py-4 font-mono text-xs text-zinc-500">{c.image}</td>
                    <td className="px-5 py-4">
                      <div className="flex items-center gap-1.5">
                        {isStopped && (
                          <ActionButton
                            label="Start"
                            color="emerald"
                            disabled={isBusy || isTransitioning}
                            onClick={() => act(c.companyId, 'start')}
                          />
                        )}
                        {isRunning && (
                          <ActionButton
                            label="Stop"
                            color="yellow"
                            disabled={isBusy || isTransitioning}
                            onClick={() => act(c.companyId, 'stop')}
                          />
                        )}
                        {(isRunning || isStopped) && (
                          <ActionButton
                            label="Restart"
                            color="blue"
                            disabled={isBusy || isTransitioning}
                            onClick={() => act(c.companyId, 'restart')}
                          />
                        )}
                        <ActionButton
                          label="Redeploy"
                          color="purple"
                          disabled={isBusy || isTransitioning}
                          onClick={() => act(c.companyId, 'deploy')}
                        />
                        <ActionButton
                          label="Logs"
                          color="zinc"
                          disabled={isBusy || !c.dockerId}
                          onClick={() => setLogsFor({ companyId: c.companyId, companyName: c.company.name })}
                        />
                        <ActionButton
                          label="Remove"
                          color="red"
                          disabled={isBusy || isTransitioning}
                          onClick={() => {
                            if (confirm(`Remove container for ${c.company.name}? This cannot be undone.`)) {
                              act(c.companyId, 'remove')
                            }
                          }}
                        />
                      </div>
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  )
}

function ActionButton({
  label,
  color,
  disabled,
  onClick,
}: {
  label: string
  color: 'emerald' | 'yellow' | 'blue' | 'purple' | 'zinc' | 'red'
  disabled: boolean
  onClick: () => void
}) {
  const colorMap: Record<string, string> = {
    emerald: 'border-emerald-800 text-emerald-400 hover:bg-emerald-900/40',
    yellow:  'border-orange-800 text-orange-400 hover:bg-orange-900/40',
    blue:    'border-blue-800 text-blue-400 hover:bg-blue-900/40',
    purple:  'border-purple-800 text-purple-400 hover:bg-purple-900/40',
    zinc:    'border-zinc-700 text-zinc-400 hover:bg-zinc-700/40',
    red:     'border-red-900 text-red-400 hover:bg-red-900/30',
  }
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`rounded-lg border px-2.5 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${colorMap[color]}`}
    >
      {label}
    </button>
  )
}
