'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { authFetch, clearToken, getApiBase, getToken } from '../lib/auth'

type DiagnosticCatalogItem = {
  key: string
  label: string
  category: string
  description: string
  live_safe: boolean
  target: string | null
  configured: boolean
  config_status: string
  config_detail: string
}

type DiagnosticResult = {
  key: string
  label: string
  category: string
  description: string
  target: string | null
  live_safe: boolean
  configured: boolean
  status: string
  message: string
  detail?: unknown
  checked_at?: string
  duration_ms?: number
}

type DiagnosticsResponse = {
  checks: DiagnosticCatalogItem[]
  categories: string[]
  generated_at: string
}

type RunDiagnosticsResponse = {
  results: DiagnosticResult[]
  summary: {
    total: number
    up: number
    down: number
    degraded: number
    not_configured: number
    disabled: number
  }
  checked_at: string
}

type RunMode = 'safe' | 'all' | 'single'

type AdminDiagnosticsPanelProps = {
  embedded?: boolean
}

const REFRESH_INTERVAL_MS = 30000

const STATUS_LABELS: Record<string, string> = {
  idle: 'Ready',
  up: 'Up',
  down: 'Down',
  degraded: 'Degraded',
  disabled: 'Disabled',
  not_configured: 'Not configured',
}

function formatCheckedAt(value?: string) {
  if (!value) return 'Not yet run'
  const parsed = new Date(value)
  if (Number.isNaN(parsed.getTime())) return value
  return parsed.toLocaleString()
}

function formatDuration(value?: number) {
  if (typeof value !== 'number' || Number.isNaN(value) || value <= 0) {
    return 'Pending'
  }
  return `${value.toFixed(1)} ms`
}

function statusLabel(status: string) {
  return STATUS_LABELS[status] ?? status
}

export default function AdminDiagnosticsPanel({ embedded = false }: AdminDiagnosticsPanelProps) {
  const router = useRouter()
  const [loading, setLoading] = useState(true)
  const [authorized, setAuthorized] = useState(false)
  const [checks, setChecks] = useState<DiagnosticCatalogItem[]>([])
  const [resultsByKey, setResultsByKey] = useState<Record<string, DiagnosticResult>>({})
  const [runningKeys, setRunningKeys] = useState<string[]>([])
  const [autoRefresh, setAutoRefresh] = useState(true)
  const [pageError, setPageError] = useState('')
  const [lastRunAt, setLastRunAt] = useState<string | null>(null)
  const [lastRunMode, setLastRunMode] = useState<RunMode | null>(null)
  const [emailRecipient, setEmailRecipient] = useState('')

  const liveSafeKeys = checks.filter((check) => check.live_safe).map((check) => check.key)

  async function runDiagnostics(keys?: string[], mode: RunMode = 'single') {
    const baseUrl = getApiBase()
    const effectiveKeys = keys && keys.length > 0 ? keys : checks.map((check) => check.key)
    if (effectiveKeys.length === 0) {
      return
    }
    setRunningKeys((current) => Array.from(new Set([...current, ...effectiveKeys])))
    setPageError('')
    try {
      const response = await authFetch(`${baseUrl}/admin/diagnostics/run`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          keys: effectiveKeys,
          ...(emailRecipient.trim() ? { recipient_email: emailRecipient.trim() } : {}),
        }),
      })
      if (response.status === 401) {
        clearToken()
        router.push('/login')
        return
      }
      if (!response.ok) {
        const text = await response.text()
        throw new Error(text || `Diagnostics run failed: ${response.status}`)
      }
      const data = (await response.json()) as { status: string } & RunDiagnosticsResponse
      const nextResults: Record<string, DiagnosticResult> = {}
      for (const result of data.results ?? []) {
        nextResults[result.key] = result
      }
      setResultsByKey((current) => ({ ...current, ...nextResults }))
      setLastRunAt(data.checked_at ?? new Date().toISOString())
      setLastRunMode(mode)
    } catch (error) {
      console.error(error)
      setPageError(error instanceof Error ? error.message : 'Diagnostics run failed.')
    } finally {
      setRunningKeys((current) => current.filter((key) => !effectiveKeys.includes(key)))
    }
  }

  useEffect(() => {
    let active = true

    const loadPage = async () => {
      if (!getToken()) {
        router.push('/login')
        return
      }
      try {
        const baseUrl = getApiBase()
        const authResponse = await authFetch(`${baseUrl}/auth/me`)
        if (!authResponse.ok) {
          if (authResponse.status === 401) {
            clearToken()
            router.push('/login')
            return
          }
          router.push('/')
          return
        }
        const me = await authResponse.json()
        if (!active) return
        if (me?.role !== 'admin') {
          router.push('/')
          return
        }

        const diagnosticsResponse = await authFetch(`${baseUrl}/admin/diagnostics`)
        if (!diagnosticsResponse.ok) {
          const text = await diagnosticsResponse.text()
          throw new Error(text || `Diagnostics load failed: ${diagnosticsResponse.status}`)
        }
        const data = (await diagnosticsResponse.json()) as { status: string } & DiagnosticsResponse
        if (!active) return
        setChecks(data.checks ?? [])
        setAuthorized(true)
        setLoading(false)
        const safeKeys = (data.checks ?? []).filter((check) => check.live_safe).map((check) => check.key)
        if (safeKeys.length > 0) {
          void runDiagnostics(safeKeys, 'safe')
        }
      } catch (error) {
        console.error(error)
        if (!active) return
        setPageError(error instanceof Error ? error.message : 'Unable to load diagnostics.')
        setLoading(false)
      }
    }

    void loadPage()

    return () => {
      active = false
    }
  }, [router])

  useEffect(() => {
    if (!authorized || !autoRefresh || liveSafeKeys.length === 0) {
      return
    }
    const interval = window.setInterval(() => {
      void runDiagnostics(liveSafeKeys, 'safe')
    }, REFRESH_INTERVAL_MS)
    return () => {
      window.clearInterval(interval)
    }
  }, [authorized, autoRefresh, liveSafeKeys.join('|')])

  if (loading) {
    return <div className="admin-panel">Loading diagnostics...</div>
  }

  if (!authorized) {
    return null
  }

  const orderedCategories: string[] = []
  for (const check of checks) {
    if (!orderedCategories.includes(check.category)) {
      orderedCategories.push(check.category)
    }
  }

  const mergedResults = checks.map((check) => {
    const result = resultsByKey[check.key]
    if (result) {
      return result
    }
    return {
      key: check.key,
      label: check.label,
      category: check.category,
      description: check.description,
      target: check.target,
      live_safe: check.live_safe,
      configured: check.configured,
      status: check.configured ? 'idle' : check.config_status,
      message: check.configured ? 'Ready to test.' : check.config_detail,
      checked_at: undefined,
      duration_ms: undefined,
    } satisfies DiagnosticResult
  })

  const summary = {
    total: mergedResults.length,
    up: 0,
    down: 0,
    degraded: 0,
    disabled: 0,
    not_configured: 0,
    idle: 0,
  }
  for (const result of mergedResults) {
    const key = result.status as keyof typeof summary
    if (key in summary) {
      summary[key] += 1
    }
  }

  return (
    <div className={`diagnostics-page${embedded ? ' diagnostics-page-embedded' : ''}`}>
      <div className="admin-panel diagnostics-control-panel">
        <div className="diagnostics-control-copy">
          <h2>{embedded ? 'Connectivity diagnostics' : 'Control center'}</h2>
          <p className="lede">
            Use live checks for Magent and service connectivity. Use run all when you want outbound notification
            channels to send a real ping through the configured provider.
          </p>
        </div>
        <div className="diagnostics-control-actions">
          <label className="diagnostics-email-recipient">
            <span>Test email recipient</span>
            <input
              type="email"
              placeholder="Leave blank to use configured sender"
              value={emailRecipient}
              onChange={(event) => setEmailRecipient(event.target.value)}
            />
          </label>
          <button
            type="button"
            className={autoRefresh ? 'is-active' : ''}
            onClick={() => setAutoRefresh((current) => !current)}
          >
            {autoRefresh ? 'Disable auto refresh' : 'Enable auto refresh'}
          </button>
          <button
            type="button"
            onClick={() => {
              void runDiagnostics(liveSafeKeys, 'safe')
            }}
            disabled={runningKeys.length > 0 || liveSafeKeys.length === 0}
          >
            Run live checks
          </button>
          <button
            type="button"
            onClick={() => {
              void runDiagnostics(undefined, 'all')
            }}
            disabled={runningKeys.length > 0 || checks.length === 0}
          >
            Run all tests
          </button>
          <span className={`small-pill ${autoRefresh ? 'is-positive' : ''}`}>
            {autoRefresh ? 'Auto refresh on' : 'Auto refresh off'}
          </span>
          <span className="small-pill">{lastRunMode ? `Last run: ${lastRunMode}` : 'No run yet'}</span>
        </div>
      </div>

      <div className="admin-panel diagnostics-inline-summary">
        <div className="diagnostics-inline-metric">
          <span>Total</span>
          <strong>{summary.total}</strong>
        </div>
        <div className="diagnostics-inline-metric">
          <span>Up</span>
          <strong>{summary.up}</strong>
        </div>
        <div className="diagnostics-inline-metric">
          <span>Degraded</span>
          <strong>{summary.degraded}</strong>
        </div>
        <div className="diagnostics-inline-metric">
          <span>Down</span>
          <strong>{summary.down}</strong>
        </div>
        <div className="diagnostics-inline-metric">
          <span>Disabled</span>
          <strong>{summary.disabled}</strong>
        </div>
        <div className="diagnostics-inline-metric">
          <span>Not configured</span>
          <strong>{summary.not_configured}</strong>
        </div>
        <div className="diagnostics-inline-last-run">
          Last completed run: {formatCheckedAt(lastRunAt ?? undefined)}
        </div>
      </div>

      {pageError ? <div className="admin-panel diagnostics-error">{pageError}</div> : null}

      {orderedCategories.map((category) => {
        const categoryChecks = mergedResults.filter((check) => check.category === category)
        return (
          <div key={category} className="admin-panel diagnostics-category-panel">
            <div className="diagnostics-category-header">
              <div>
                <h2>{category}</h2>
                <p>{category === 'Notifications' ? 'These tests can emit real messages.' : 'Safe live health checks.'}</p>
              </div>
              <span className="small-pill">{categoryChecks.length} checks</span>
            </div>

            <div className="diagnostics-grid">
              {categoryChecks.map((check) => {
                const isRunning = runningKeys.includes(check.key)
                return (
                  <article key={check.key} className={`diagnostic-card diagnostic-card-${check.status}`}>
                    <div className="diagnostic-card-top">
                      <div className="diagnostic-card-copy">
                        <div className="diagnostic-card-title-row">
                          <h3>{check.label}</h3>
                          <span className={`system-pill system-pill-${check.status}`}>{statusLabel(check.status)}</span>
                        </div>
                        <p>{check.description}</p>
                      </div>
                      <button
                        type="button"
                        className="system-test"
                        onClick={() => {
                          void runDiagnostics([check.key], 'single')
                        }}
                        disabled={isRunning}
                      >
                        {check.live_safe ? 'Ping' : 'Send test'}
                      </button>
                    </div>

                    <div className="diagnostic-meta-grid">
                      <div className="diagnostic-meta-item">
                        <span>Target</span>
                        <strong>{check.target || 'Not set'}</strong>
                      </div>
                      <div className="diagnostic-meta-item">
                        <span>Latency</span>
                        <strong>{formatDuration(check.duration_ms)}</strong>
                      </div>
                      <div className="diagnostic-meta-item">
                        <span>Mode</span>
                        <strong>{check.live_safe ? 'Live safe' : 'Manual only'}</strong>
                      </div>
                      <div className="diagnostic-meta-item">
                        <span>Last checked</span>
                        <strong>{formatCheckedAt(check.checked_at)}</strong>
                      </div>
                    </div>

                    <div className={`diagnostic-message diagnostic-message-${check.status}`}>
                      <span className="system-dot" />
                      <span>{isRunning ? 'Running diagnostic...' : check.message}</span>
                    </div>
                  </article>
                )
              })}
            </div>
          </div>
        )
      })}
    </div>
  )
}
