import { useEffect, useRef, useState } from 'react'
import { APP_NAME } from '@/constants/app.constant'
import { getMigrateUrl } from '@/services/setup.service'
import { applicationConfigurationUrl, getAppConfig } from '@/services/abpConfig.service'

interface LogLine {
  level: 'info' | 'warn' | 'error' | 'success' | 'restart' | 'done'
  message: string
}

type MigrationStatus = 'idle' | 'running' | 'success' | 'error' | 'restarting'

const levelClass: Record<string, string> = {
  info: 'text-gray-300',
  warn: 'text-yellow-400',
  error: 'text-red-400',
  success: 'text-green-400',
  restart: 'text-blue-400',
  done: 'text-blue-400',
}

const DatabaseSetup = () => {
  const [logs, setLogs] = useState<LogLine[]>([])
  const [status, setStatus] = useState<MigrationStatus>('idle')
  const [pollCountdown, setPollCountdown] = useState(0)
  const logEndRef = useRef<HTMLDivElement>(null)
  const eventSourceRef = useRef<EventSource | null>(null)
  const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Auto-scroll to bottom when new logs arrive
  useEffect(() => {
    logEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }, [logs])

  // Cleanup on component unmount
  useEffect(() => {
    return () => {
      eventSourceRef.current?.close()
      if (pollTimerRef.current) clearTimeout(pollTimerRef.current)
    }
  }, [])

  const addLog = (level: LogLine['level'], message: string) => {
    setLogs((prev) => [...prev, { level, message }])
  }

  // ── Poll ABP config endpoint until server is ready ──────────────
  const pollUntilReady = () => {
    setStatus('restarting')

    let attempt = 0

    const tick = async () => {
      attempt++
      setPollCountdown(attempt)
      try {
        const res = await fetch(applicationConfigurationUrl(false), { method: 'GET' })
        if (res.status !== 503) {
          // Full ABP application is ready — reload the page
          window.location.href = '/'
          return
        }
      } catch {
        // Server not responding yet — expected, retry
      }
      pollTimerRef.current = setTimeout(tick, 2000)
    }

    // İlk denemeden önce kısa bir bekleme (sunucunun kapanma süresi)
    pollTimerRef.current = setTimeout(tick, 2500)
  }

  const startMigration = () => {
    if (status === 'running') return

    setLogs([])
    setStatus('running')
    addLog('info', 'Starting migration...')

    const url = getMigrateUrl()
    const es = new EventSource(url)
    eventSourceRef.current = es

    es.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data) as { level?: string; message?: string }
        const level = (data.level ?? 'info') as LogLine['level']
        const message = data.message ?? event.data

        if (level === 'done') {
          es.close()
          eventSourceRef.current = null
          // If we received a "restart" event, switch to poll mode; otherwise keep success/error state
          setStatus((prev) => {
            if (prev === 'running') return 'error' // failed — no restart event received
            return prev
          })
          return
        }

        addLog(level, message)

        if (level === 'success') {
          setStatus('success')
        } else if (level === 'error') {
          setStatus('error')
        } else if (level === 'restart') {
          // Backend is stopping the minimal app — start polling
          pollUntilReady()
        }
      } catch {
        addLog('info', event.data)
      }
    }

    es.onerror = () => {
      es.close()
      eventSourceRef.current = null
      setStatus((prev) => (prev === 'running' ? 'error' : prev))
      addLog('error', 'Server connection lost or migration could not be completed.')
    }
  }

  return (
    <div className="min-h-screen bg-gray-900 flex flex-col items-center justify-center p-6 text-white">
      {/* Header */}
      <div className="mb-8 text-center">
        <h1 className="text-3xl font-bold mb-2">{APP_NAME}</h1>
        <p className="text-gray-400 text-lg">Initial Setup — Creating Database</p>
      </div>

      {/* Status Card */}
      <div className="w-full max-w-4xl bg-gray-800 rounded-xl shadow-2xl overflow-hidden">
        {/* Card Header */}
        <div className="flex items-center justify-between px-5 py-4 bg-gray-700 border-b border-gray-600">
          <div className="flex items-center gap-3">
            <StatusIndicator status={status} />
            <span className="font-semibold text-sm tracking-wide">
              {status === 'idle' && 'Ready to Setup'}
              {status === 'running' && 'Migration Running...'}
              {status === 'success' && 'Migration Completed ✓'}
              {status === 'restarting' && `Server Restarting... (attempt ${pollCountdown})`}
              {status === 'error' && 'Migration Failed ✗'}
            </span>
          </div>
          <span className="text-xs text-gray-400">{logs.length} log lines</span>
        </div>

        {/* Log Terminal */}
        <div className="h-96 overflow-y-auto bg-gray-950 px-4 py-3 font-mono text-xs leading-relaxed">
          {logs.length === 0 ? (
            <p className="text-gray-600 mt-2">Logs will appear here when migration starts...</p>
          ) : (
            logs.map((line, i) => (
              <div key={i} className={`${levelClass[line.level] ?? 'text-gray-300'} mb-0.5`}>
                <span className="text-gray-600 mr-2 select-none">{String(i + 1).padStart(4, '0')}</span>
                {line.message}
              </div>
            ))
          )}
          <div ref={logEndRef} />
        </div>

        {/* Action Area */}
        <div className="flex items-center justify-between px-5 py-4 bg-gray-700 border-t border-gray-600">
          <div className="text-xs text-gray-400">
            {status === 'idle' && 'Database not found. Press the button to start migration.'}
            {status === 'running' && 'Please wait, migration is in progress...'}
            {status === 'success' && 'Migration completed. Server is restarting...'}
            {status === 'restarting' &&
              'Waiting for application server to be ready, you will be redirected automatically...'}
            {status === 'error' &&
              'Review the errors in the logs, fix the issue, and try again.'}
          </div>

          <div className="flex gap-3">
            {(status === 'idle' || status === 'error') && (
              <button
                onClick={startMigration}
                className="px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-medium rounded-lg transition-colors"
              >
                {status === 'error' ? 'Retry' : 'Start Setup'}
              </button>
            )}

            {status === 'restarting' && (
              <div className="flex items-center gap-2 text-blue-400 text-sm">
                <span className="inline-block w-3 h-3 rounded-full bg-blue-400 animate-ping" />
                Waiting...
              </div>
            )}
          </div>
        </div>
      </div>

      <p className="mt-6 text-xs text-gray-600">
        This page is only visible when the database does not exist.
      </p>
    </div>
  )
}

// ─── Status Indicator ────────────────────────────────────────────────────────

const StatusIndicator = ({ status }: { status: MigrationStatus }) => {
  const cls: Record<MigrationStatus, string> = {
    idle: 'bg-gray-500',
    running: 'bg-yellow-400 animate-pulse',
    success: 'bg-green-500',
    restarting: 'bg-blue-400 animate-ping',
    error: 'bg-red-500',
  }
  return <span className={`inline-block w-3 h-3 rounded-full ${cls[status]}`} />
}

export default DatabaseSetup


