'use client'

import { useState, useMemo, useEffect, useCallback } from 'react'
import Link from 'next/link'
import { useParams, useRouter } from 'next/navigation'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { useOrder, useUpdateOrder, useTriggerProvisioning } from '@/hooks/use-orders'
import { useProvisioningLogs, StreamedLog } from '@/hooks/use-provisioning-logs'
import { OrderStatus, SubscriptionTier, LogLevel } from '@/types/api'
import {
  ArrowLeft,
  Globe,
  User,
  Server,
  Clock,
  CheckCircle,
  AlertCircle,
  Loader2,
  Eye,
  EyeOff,
  RefreshCw,
  ExternalLink,
  Terminal,
  Zap,
  Wifi,
  WifiOff,
} from 'lucide-react'

// Status badge component
function StatusBadge({ status }: { status: OrderStatus }) {
  const statusConfig: Record<OrderStatus, { label: string; className: string }> = {
    PAYMENT_CONFIRMED: { label: 'Payment Confirmed', className: 'bg-blue-100 text-blue-800' },
    AWAITING_SERVER: { label: 'Awaiting Server', className: 'bg-yellow-100 text-yellow-800' },
    SERVER_READY: { label: 'Server Ready', className: 'bg-purple-100 text-purple-800' },
    DNS_PENDING: { label: 'DNS Pending', className: 'bg-orange-100 text-orange-800' },
    DNS_READY: { label: 'DNS Ready', className: 'bg-cyan-100 text-cyan-800' },
    PROVISIONING: { label: 'Provisioning', className: 'bg-indigo-100 text-indigo-800' },
    FULFILLED: { label: 'Fulfilled', className: 'bg-green-100 text-green-800' },
    EMAIL_CONFIGURED: { label: 'Complete', className: 'bg-emerald-100 text-emerald-800' },
    FAILED: { label: 'Failed', className: 'bg-red-100 text-red-800' },
  }

  const config = statusConfig[status]

  return (
    <span className={`inline-flex items-center rounded-full px-3 py-1 text-sm font-medium ${config.className}`}>
      {config.label}
    </span>
  )
}

// Server credentials form component
function ServerCredentialsForm({
  initialIp,
  initialPort,
  hasCredentials,
  onSubmit,
  isLoading,
}: {
  initialIp?: string
  initialPort?: number
  hasCredentials: boolean
  onSubmit: (ip: string, password: string, port: number) => void
  isLoading: boolean
}) {
  const [ip, setIp] = useState(initialIp || '')
  const [password, setPassword] = useState('')
  const [port, setPort] = useState(String(initialPort || 22))
  const [showPassword, setShowPassword] = useState(false)
  const [testing, setTesting] = useState(false)
  const [testResult, setTestResult] = useState<{ success: boolean; message: string } | null>(null)

  const handleTestConnection = async () => {
    setTesting(true)
    setTestResult(null)
    // TODO: Call API to test SSH connection
    await new Promise(resolve => setTimeout(resolve, 2000))
    setTestResult({ success: true, message: 'Connection successful! SSH version: OpenSSH_8.4' })
    setTesting(false)
  }

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    onSubmit(ip, password, parseInt(port))
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Server className="h-5 w-5" />
          Server Credentials
        </CardTitle>
        <CardDescription>
          {hasCredentials
            ? 'Server credentials have been entered. You can update them if needed.'
            : 'Enter the server credentials received from the hosting provider.'}
        </CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="ip">Server IP Address</Label>
              <Input
                id="ip"
                type="text"
                placeholder="123.45.67.89"
                value={ip}
                onChange={(e) => setIp(e.target.value)}
                required
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="port">SSH Port</Label>
              <Input
                id="port"
                type="number"
                placeholder="22"
                value={port}
                onChange={(e) => setPort(e.target.value)}
                required
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label htmlFor="password">Root Password</Label>
            <div className="relative">
              <Input
                id="password"
                type={showPassword ? 'text' : 'password'}
                placeholder="Enter root password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                required={!hasCredentials}
                className="pr-10"
              />
              <Button
                type="button"
                variant="ghost"
                size="icon"
                className="absolute right-0 top-0 h-full px-3 hover:bg-transparent"
                onClick={() => setShowPassword(!showPassword)}
              >
                {showPassword ? (
                  <EyeOff className="h-4 w-4 text-muted-foreground" />
                ) : (
                  <Eye className="h-4 w-4 text-muted-foreground" />
                )}
              </Button>
            </div>
            <p className="text-xs text-muted-foreground">
              Password will be encrypted and deleted after provisioning completes.
            </p>
          </div>

          {testResult && (
            <div
              className={`flex items-center gap-2 rounded-md p-3 ${
                testResult.success ? 'bg-green-50 text-green-800' : 'bg-red-50 text-red-800'
              }`}
            >
              {testResult.success ? (
                <CheckCircle className="h-4 w-4" />
              ) : (
                <AlertCircle className="h-4 w-4" />
              )}
              <span className="text-sm">{testResult.message}</span>
            </div>
          )}

          <div className="flex gap-3">
            <Button
              type="button"
              variant="outline"
              onClick={handleTestConnection}
              disabled={!ip || !password || testing}
            >
              {testing ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Testing...
                </>
              ) : (
                <>
                  <RefreshCw className="mr-2 h-4 w-4" />
                  Test Connection
                </>
              )}
            </Button>
            <Button type="submit" disabled={isLoading || !ip}>
              {isLoading ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Saving...
                </>
              ) : (
                'Save & Mark Ready'
              )}
            </Button>
          </div>
        </form>
      </CardContent>
    </Card>
  )
}

// Provisioning logs component
function ProvisioningLogs({ logs, isLive, isConnected, onReconnect }: {
  logs: Array<{
    id: string
    timestamp: Date
    level: LogLevel
    step: string | null
    message: string
  }>
  isLive: boolean
  isConnected?: boolean
  onReconnect?: () => void
}) {
  const levelColors: Record<LogLevel, string> = {
    INFO: 'text-blue-400',
    WARN: 'text-yellow-400',
    ERROR: 'text-red-400',
    DEBUG: 'text-gray-400',
  }

  const formatTime = (date: Date) => {
    const d = new Date(date)
    return d.toLocaleTimeString('en-US', { hour12: false })
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle className="flex items-center gap-2">
              <Terminal className="h-5 w-5" />
              Provisioning Logs
            </CardTitle>
            <CardDescription>Real-time output from the provisioning process</CardDescription>
          </div>
          <div className="flex items-center gap-3">
            {isLive && (
              <>
                {isConnected ? (
                  <div className="flex items-center gap-2">
                    <span className="relative flex h-3 w-3">
                      <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75"></span>
                      <span className="relative inline-flex h-3 w-3 rounded-full bg-green-500"></span>
                    </span>
                    <span className="text-sm text-muted-foreground">Live</span>
                    <Wifi className="h-4 w-4 text-green-500" />
                  </div>
                ) : (
                  <div className="flex items-center gap-2">
                    <WifiOff className="h-4 w-4 text-red-500" />
                    <span className="text-sm text-red-500">Disconnected</span>
                    {onReconnect && (
                      <Button variant="ghost" size="sm" onClick={onReconnect}>
                        <RefreshCw className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                )}
              </>
            )}
            {!isLive && logs.length > 0 && (
              <span className="text-sm text-muted-foreground">
                {logs.length} log{logs.length !== 1 ? 's' : ''}
              </span>
            )}
          </div>
        </div>
      </CardHeader>
      <CardContent>
        <div className="h-96 overflow-y-auto rounded-lg bg-gray-900 p-4 font-mono text-sm" id="log-container">
          {logs.length === 0 ? (
            <p className="text-gray-500">
              {isLive && isConnected ? 'Waiting for logs...' : 'No logs available yet.'}
            </p>
          ) : (
            logs.map((log) => (
              <div key={log.id} className="mb-2">
                <span className="text-gray-500">[{formatTime(log.timestamp)}]</span>{' '}
                <span className={levelColors[log.level]}>[{log.level}]</span>{' '}
                {log.step && <span className="text-purple-400">[{log.step}]</span>}{' '}
                <span className="text-gray-300">{log.message}</span>
              </div>
            ))
          )}
        </div>
      </CardContent>
    </Card>
  )
}

// Order timeline component
function OrderTimeline({
  status,
  timestamps,
}: {
  status: OrderStatus
  timestamps: {
    createdAt?: Date | null
    serverReadyAt?: Date | null
    provisioningStartedAt?: Date | null
    completedAt?: Date | null
  }
}) {
  const stages = [
    { key: 'payment_confirmed', label: 'Payment Confirmed', status: 'PAYMENT_CONFIRMED' },
    { key: 'awaiting_server', label: 'Server Ordered', status: 'AWAITING_SERVER' },
    { key: 'server_ready', label: 'Server Ready', status: 'SERVER_READY' },
    { key: 'dns_ready', label: 'DNS Configured', status: 'DNS_READY' },
    { key: 'provisioning', label: 'Provisioning', status: 'PROVISIONING' },
    { key: 'fulfilled', label: 'Fulfilled', status: 'FULFILLED' },
  ]

  const statusOrder = stages.map((s) => s.status)
  const currentIndex = statusOrder.indexOf(status)

  const formatDate = (date: Date | null | undefined) => {
    if (!date) return null
    return new Date(date).toLocaleString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric',
      hour: 'numeric',
      minute: '2-digit',
      hour12: true,
    })
  }

  const getTimestamp = (key: string): string | null => {
    switch (key) {
      case 'payment_confirmed':
        return formatDate(timestamps.createdAt)
      case 'server_ready':
        return formatDate(timestamps.serverReadyAt)
      case 'provisioning':
        return formatDate(timestamps.provisioningStartedAt)
      case 'fulfilled':
        return formatDate(timestamps.completedAt)
      default:
        return null
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <Clock className="h-5 w-5" />
          Order Timeline
        </CardTitle>
      </CardHeader>
      <CardContent>
        <div className="relative">
          {stages.map((stage, index) => {
            const isComplete = index < currentIndex || (index === currentIndex && status !== 'FAILED')
            const isCurrent = index === currentIndex
            const timestamp = getTimestamp(stage.key)

            return (
              <div key={stage.key} className="flex gap-4 pb-8 last:pb-0">
                <div className="relative flex flex-col items-center">
                  <div
                    className={`flex h-8 w-8 items-center justify-center rounded-full border-2 ${
                      isComplete
                        ? 'border-green-500 bg-green-500 text-white'
                        : isCurrent
                        ? 'border-blue-500 bg-blue-50'
                        : 'border-gray-200 bg-white'
                    }`}
                  >
                    {isComplete ? (
                      <CheckCircle className="h-4 w-4" />
                    ) : (
                      <span className="text-sm font-medium">{index + 1}</span>
                    )}
                  </div>
                  {index < stages.length - 1 && (
                    <div
                      className={`absolute top-8 h-full w-0.5 ${
                        isComplete ? 'bg-green-500' : 'bg-gray-200'
                      }`}
                    />
                  )}
                </div>
                <div className="flex-1 pt-1">
                  <p className={`font-medium ${isCurrent ? 'text-blue-600' : ''}`}>
                    {stage.label}
                  </p>
                  {timestamp && (
                    <p className="text-sm text-muted-foreground">{timestamp}</p>
                  )}
                </div>
              </div>
            )
          })}
        </div>
      </CardContent>
    </Card>
  )
}

export default function OrderDetailPage() {
  const params = useParams()
  const router = useRouter()
  const orderId = params.id as string

  // Fetch order data
  const {
    data: order,
    isLoading,
    isError,
    error,
    refetch,
    isFetching,
  } = useOrder(orderId)

  // Mutations
  const updateOrder = useUpdateOrder()
  const triggerProvision = useTriggerProvisioning()

  // Check if we should enable SSE streaming
  const isProvisioning = order?.status === OrderStatus.PROVISIONING

  // SSE for live log streaming
  const {
    logs: streamedLogs,
    isConnected,
    isComplete,
    reconnect,
  } = useProvisioningLogs({
    orderId,
    enabled: isProvisioning,
    onStatusChange: useCallback((newStatus: OrderStatus) => {
      // Refetch order data when status changes
      refetch()
    }, [refetch]),
    onComplete: useCallback((success: boolean) => {
      // Refetch order data when provisioning completes
      refetch()
    }, [refetch]),
  })

  // Computed values
  const tierLabel = useMemo(() => {
    if (!order) return ''
    return order.tier === SubscriptionTier.HUB_DASHBOARD ? 'Hub Dashboard' : 'Control Panel'
  }, [order?.tier])

  // Merge historical logs with streamed logs, avoiding duplicates
  const allLogs = useMemo(() => {
    const historicalLogs = order?.provisioningLogs || []
    const historicalLogIds = new Set(historicalLogs.map(l => l.id))

    // Add only new streamed logs that aren't in historical
    const newStreamedLogs = streamedLogs.filter(l => !historicalLogIds.has(l.id))

    // Combine and sort by timestamp
    const combined = [
      ...historicalLogs.map(l => ({
        id: l.id,
        level: l.level,
        step: l.step,
        message: l.message,
        timestamp: new Date(l.timestamp),
      })),
      ...newStreamedLogs,
    ]

    return combined.sort(
      (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
    )
  }, [order?.provisioningLogs, streamedLogs])

  // Auto-scroll logs to bottom when new logs come in
  useEffect(() => {
    if (isProvisioning && allLogs.length > 0) {
      const container = document.getElementById('log-container')
      if (container) {
        container.scrollTop = container.scrollHeight
      }
    }
  }, [allLogs.length, isProvisioning])

  const handleCredentialsSubmit = async (ip: string, password: string, port: number) => {
    await updateOrder.mutateAsync({
      id: orderId,
      data: {
        serverIp: ip,
        serverPassword: password,
        sshPort: port,
      },
    })
  }

  const handleTriggerProvisioning = async () => {
    try {
      await triggerProvision.mutateAsync(orderId)
    } catch (err) {
      console.error('Failed to trigger provisioning:', err)
    }
  }

  // Loading state
  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-[50vh]">
        <div className="flex flex-col items-center gap-4">
          <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
          <p className="text-muted-foreground">Loading order details...</p>
        </div>
      </div>
    )
  }

  // Error state
  if (isError || !order) {
    return (
      <div className="flex items-center justify-center h-[50vh]">
        <div className="flex flex-col items-center gap-4 text-center">
          <AlertCircle className="h-8 w-8 text-destructive" />
          <div>
            <p className="font-medium text-destructive">Failed to load order</p>
            <p className="text-sm text-muted-foreground">
              {error instanceof Error ? error.message : 'Order not found'}
            </p>
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={() => router.back()}>
              <ArrowLeft className="h-4 w-4 mr-2" />
              Go Back
            </Button>
            <Button variant="outline" onClick={() => refetch()}>
              <RefreshCw className="h-4 w-4 mr-2" />
              Retry
            </Button>
          </div>
        </div>
      </div>
    )
  }

  const showCredentialsForm = order.status === OrderStatus.AWAITING_SERVER || order.status === OrderStatus.SERVER_READY
  const showProvisionButton = order.status === OrderStatus.DNS_READY || order.status === OrderStatus.FAILED
  const showLogs = order.status === OrderStatus.PROVISIONING ||
                   order.status === OrderStatus.FULFILLED ||
                   order.status === OrderStatus.EMAIL_CONFIGURED ||
                   order.status === OrderStatus.FAILED

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Link href="/admin/orders">
          <Button variant="ghost" size="icon">
            <ArrowLeft className="h-5 w-5" />
          </Button>
        </Link>
        <div className="flex-1">
          <div className="flex items-center gap-3">
            <h1 className="text-2xl font-bold">{order.domain}</h1>
            <StatusBadge status={order.status} />
          </div>
          <p className="text-muted-foreground">Order #{orderId.slice(0, 8)}...</p>
        </div>
        <div className="flex gap-2">
          <Button
            variant="ghost"
            size="sm"
            onClick={() => refetch()}
            disabled={isFetching}
          >
            <RefreshCw className={`h-4 w-4 mr-2 ${isFetching ? 'animate-spin' : ''}`} />
            Refresh
          </Button>
          {showProvisionButton && (
            <Button
              onClick={handleTriggerProvisioning}
              disabled={triggerProvision.isPending}
            >
              {triggerProvision.isPending ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Starting...
                </>
              ) : (
                <>
                  <Zap className="mr-2 h-4 w-4" />
                  {order.status === OrderStatus.FAILED ? 'Retry Provisioning' : 'Start Provisioning'}
                </>
              )}
            </Button>
          )}
          {order.portainerUrl && (
            <Button variant="outline" asChild>
              <a href={order.portainerUrl} target="_blank" rel="noopener noreferrer">
                <ExternalLink className="mr-2 h-4 w-4" />
                Portainer
              </a>
            </Button>
          )}
          {order.dashboardUrl && (
            <Button variant="outline" asChild>
              <a href={order.dashboardUrl} target="_blank" rel="noopener noreferrer">
                <ExternalLink className="mr-2 h-4 w-4" />
                Dashboard
              </a>
            </Button>
          )}
        </div>
      </div>

      {/* Failure reason banner */}
      {order.status === OrderStatus.FAILED && order.failureReason && (
        <div className="flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-4">
          <AlertCircle className="h-5 w-5 text-red-500 mt-0.5" />
          <div>
            <p className="font-medium text-red-800">Provisioning Failed</p>
            <p className="text-sm text-red-700">{order.failureReason}</p>
          </div>
        </div>
      )}

      {/* Order info cards */}
      <div className="grid gap-6 lg:grid-cols-3">
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <User className="h-5 w-5" />
              Customer
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <p className="font-medium">{order.user.name || order.user.company || 'N/A'}</p>
            <p className="text-sm text-muted-foreground">{order.user.email}</p>
            {order.user.company && order.user.name && (
              <p className="text-sm text-muted-foreground">{order.user.company}</p>
            )}
            <Link href={`/admin/customers/${order.user.id}`}>
              <Button variant="link" className="px-0 h-auto">
                View Customer Profile
              </Button>
            </Link>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Globe className="h-5 w-5" />
              Domain & Tier
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <p className="font-medium">{order.domain}</p>
            <span className="inline-flex items-center rounded-full bg-primary/10 px-2 py-1 text-xs font-medium text-primary">
              {tierLabel}
            </span>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Server className="h-5 w-5" />
              Server
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            {order.serverIp ? (
              <>
                <p className="font-mono font-medium">{order.serverIp}</p>
                <p className="text-sm text-muted-foreground">SSH Port: {order.sshPort || 22}</p>
              </>
            ) : (
              <p className="text-sm text-muted-foreground">Not configured</p>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Tools list */}
      <Card>
        <CardHeader>
          <CardTitle>Selected Tools</CardTitle>
          <CardDescription>Tools to be deployed on this server</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="flex flex-wrap gap-2">
            {order.tools.map((tool) => (
              <span
                key={tool}
                className="rounded-full bg-gray-100 px-3 py-1 text-sm font-medium capitalize"
              >
                {tool}
              </span>
            ))}
          </div>
        </CardContent>
      </Card>

      {/* Server credentials form (show for AWAITING_SERVER or SERVER_READY status) */}
      {showCredentialsForm && (
        <ServerCredentialsForm
          initialIp={order.serverIp || undefined}
          initialPort={order.sshPort}
          hasCredentials={!!order.serverIp}
          onSubmit={handleCredentialsSubmit}
          isLoading={updateOrder.isPending}
        />
      )}

      {/* Two column layout for timeline and logs */}
      <div className="grid gap-6 lg:grid-cols-2">
        <OrderTimeline
          status={order.status}
          timestamps={{
            createdAt: order.createdAt,
            serverReadyAt: order.serverReadyAt,
            provisioningStartedAt: order.provisioningStartedAt,
            completedAt: order.completedAt,
          }}
        />

        {/* Show logs for provisioning/completed/failed status */}
        {showLogs && (
          <ProvisioningLogs
            logs={allLogs}
            isLive={isProvisioning}
            isConnected={isConnected}
            onReconnect={reconnect}
          />
        )}
      </div>

      {/* Jobs history */}
      {order.jobs && order.jobs.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle>Job History</CardTitle>
            <CardDescription>Recent provisioning job attempts</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-3">
              {order.jobs.map((job) => (
                <div
                  key={job.id}
                  className="flex items-center justify-between rounded-lg border p-3"
                >
                  <div className="flex items-center gap-3">
                    <div
                      className={`h-2 w-2 rounded-full ${
                        job.status === 'COMPLETED'
                          ? 'bg-green-500'
                          : job.status === 'FAILED'
                          ? 'bg-red-500'
                          : job.status === 'RUNNING'
                          ? 'bg-blue-500'
                          : 'bg-gray-400'
                      }`}
                    />
                    <div>
                      <p className="text-sm font-medium">
                        Attempt {job.attempt} of {job.maxAttempts}
                      </p>
                      <p className="text-xs text-muted-foreground">
                        {new Date(job.createdAt).toLocaleString()}
                      </p>
                    </div>
                  </div>
                  <div className="text-right">
                    <span
                      className={`text-xs font-medium ${
                        job.status === 'COMPLETED'
                          ? 'text-green-600'
                          : job.status === 'FAILED'
                          ? 'text-red-600'
                          : job.status === 'RUNNING'
                          ? 'text-blue-600'
                          : 'text-gray-600'
                      }`}
                    >
                      {job.status}
                    </span>
                    {job.error && (
                      <p className="text-xs text-red-500 max-w-xs truncate">{job.error}</p>
                    )}
                  </div>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      )}
    </div>
  )
}
