import { Head } from '@inertiajs/react'
import IconArrowBigUpLines from '@tabler/icons-react/dist/esm/icons/IconArrowBigUpLines'
import IconCheck from '@tabler/icons-react/dist/esm/icons/IconCheck'
import IconAlertCircle from '@tabler/icons-react/dist/esm/icons/IconAlertCircle'
import IconRefresh from '@tabler/icons-react/dist/esm/icons/IconRefresh'
import SettingsLayout from '~/layouts/SettingsLayout'
import StyledButton from '~/components/StyledButton'
import Alert from '~/components/Alert'
import { useEffect, useState } from 'react'
import { IconCircleCheck } from '@tabler/icons-react'
import { SystemUpdateStatus } from '../../../types/system'
import api from '~/lib/api'

export default function SystemUpdatePage(props: {
  system: {
    updateAvailable: boolean
    latestVersion: string
    currentVersion: string
  }
}) {
  const [isUpdating, setIsUpdating] = useState(false)
  const [updateStatus, setUpdateStatus] = useState<SystemUpdateStatus | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [showLogs, setShowLogs] = useState(false)
  const [logs, setLogs] = useState<string>('')

  useEffect(() => {
    if (!isUpdating) return

    const interval = setInterval(async () => {
      try {
        const response = await api.getSystemUpdateStatus()
        if (!response) {
          throw new Error('Failed to fetch update status')
        }
        setUpdateStatus(response)

        // Check if update is complete or errored
        if (response.stage === 'complete') {
          // Give a moment for the new container to fully start
          setTimeout(() => {
            window.location.reload()
          }, 2000)
        } else if (response.stage === 'error') {
          setIsUpdating(false)
          setError(response.message)
        }
      } catch (err) {
        // During container restart, we'll lose connection - this is expected
        // Continue polling to detect when the container comes back up
        console.log('Polling update status (container may be restarting)...')
      }
    }, 2000)

    return () => clearInterval(interval)
  }, [isUpdating])

  // Poll health endpoint when update is in recreating stage
  useEffect(() => {
    if (updateStatus?.stage !== 'recreating') return

    const interval = setInterval(async () => {
      try {
        const response = await api.healthCheck()
        if (!response) {
          throw new Error('Health check failed')
        }
        if (response.status === 'ok') {
          // Reload page when container is back up
          window.location.reload()
        }
      } catch (err) {
        // Still restarting, continue polling...
      }
    }, 3000)

    return () => clearInterval(interval)
  }, [updateStatus?.stage])

  const handleStartUpdate = async () => {
    try {
      setError(null)
      setIsUpdating(true)
      const response = await api.startSystemUpdate()
      if (!response || !response.success) {
        throw new Error('Failed to start update')
      }
    } catch (err: any) {
      setIsUpdating(false)
      setError(err.response?.data?.error || err.message || 'Failed to start update')
    }
  }

  const handleViewLogs = async () => {
    try {
      const response = await api.getSystemUpdateLogs()
      if (!response) {
        throw new Error('Failed to fetch update logs')
      }
      setLogs(response.logs)
      setShowLogs(true)
    } catch (err) {
      setError('Failed to fetch update logs')
    }
  }

  const getProgressBarColor = () => {
    if (updateStatus?.stage === 'error') return 'bg-desert-red'
    if (updateStatus?.stage === 'complete') return 'bg-desert-olive'
    return 'bg-desert-green'
  }

  const getStatusIcon = () => {
    if (updateStatus?.stage === 'complete')
      return <IconCheck className="h-12 w-12 text-desert-olive" />
    if (updateStatus?.stage === 'error')
      return <IconAlertCircle className="h-12 w-12 text-desert-red" />
    if (isUpdating) return <IconRefresh className="h-12 w-12 text-desert-green animate-spin" />
    if (props.system.updateAvailable) return <IconArrowBigUpLines className="h-16 w-16 text-desert-green" />
    return <IconCircleCheck className="h-16 w-16 text-desert-olive" />
  }

  return (
    <SettingsLayout>
      <Head title="System Update" />
      <div className="xl:pl-72 w-full">
        <main className="px-6 lg:px-12 py-6 lg:py-8">
          <div className="mb-8">
            <h1 className="text-4xl font-bold text-desert-green mb-2">System Update</h1>
            <p className="text-desert-stone-dark">
              Keep your Project N.O.M.A.D. instance up to date with the latest features and improvements.
            </p>
          </div>

          {error && (
            <div className="mb-6">
              <Alert
                type="error"
                title="Update Failed"
                message={error}
                variant="bordered"
                dismissible
                onDismiss={() => setError(null)}
              />
            </div>
          )}
          {isUpdating && updateStatus?.stage === 'recreating' && (
            <div className="mb-6">
              <Alert
                type="info"
                title="Container Restarting"
                message="The admin container is restarting. This page will reload automatically when the update is complete."
                variant="solid"
              />
            </div>
          )}
          <div className="bg-white rounded-lg border shadow-md overflow-hidden">
            <div className="p-8 text-center">
              <div className="flex justify-center mb-4">{getStatusIcon()}</div>

              {!isUpdating && (
                <>
                  <h2 className="text-2xl font-bold text-desert-green mb-2">
                    {props.system.updateAvailable
                      ? 'Update Available'
                      : 'System Up to Date'}
                  </h2>
                  <p className="text-desert-stone-dark mb-6">
                    {props.system.updateAvailable
                      ? `A new version (${props.system.latestVersion}) is available for your Project N.O.M.A.D. instance.`
                      : 'Your system is running the latest version!'}
                  </p>
                </>
              )}

              {isUpdating && updateStatus && (
                <>
                  <h2 className="text-2xl font-bold text-desert-green mb-2 capitalize">
                    {updateStatus.stage === 'idle' ? 'Preparing Update' : updateStatus.stage}
                  </h2>
                  <p className="text-desert-stone-dark mb-6">{updateStatus.message}</p>
                </>
              )}

              <div className="flex justify-center gap-8 mb-6">
                <div className="text-center">
                  <p className="text-sm text-desert-stone mb-1">Current Version</p>
                  <p className="text-xl font-bold text-desert-green">
                    {props.system.currentVersion}
                  </p>
                </div>
                {props.system.updateAvailable && (
                  <>
                    <div className="flex items-center">
                      <svg
                        className="h-6 w-6 text-desert-stone"
                        fill="none"
                        stroke="currentColor"
                        viewBox="0 0 24 24"
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          strokeWidth={2}
                          d="M13 7l5 5m0 0l-5 5m5-5H6"
                        />
                      </svg>
                    </div>
                    <div className="text-center">
                      <p className="text-sm text-desert-stone mb-1">Latest Version</p>
                      <p className="text-xl font-bold text-desert-olive">
                        {props.system.latestVersion}
                      </p>
                    </div>
                  </>
                )}
              </div>
              {isUpdating && updateStatus && (
                <div className="mb-4">
                  <div className="w-full bg-desert-stone-light rounded-full h-3 overflow-hidden">
                    <div
                      className={`${getProgressBarColor()} h-full transition-all duration-500 ease-out`}
                      style={{ width: `${updateStatus.progress}%` }}
                    />
                  </div>
                  <p className="text-sm text-desert-stone mt-2">
                    {updateStatus.progress}% complete
                  </p>
                </div>
              )}
              {!isUpdating && (
                <div className="flex justify-center gap-4">
                  <StyledButton
                    variant="primary"
                    size="lg"
                    icon="ArrowDownTrayIcon"
                    onClick={handleStartUpdate}
                    disabled={!props.system.updateAvailable}
                  >
                    {props.system.updateAvailable ? 'Start Update' : 'No Update Available'}
                  </StyledButton>
                  <StyledButton
                    variant="ghost"
                    size="lg"
                    icon="ArrowPathIcon"
                    onClick={() => window.location.reload()}
                  >
                    Check Again
                  </StyledButton>
                </div>
              )}
            </div>
            <div className="border-t bg-white p-6">
              <h3 className="text-lg font-semibold text-desert-green mb-4">
                What happens during an update?
              </h3>
              <div className="space-y-3">
                <div className="flex items-start gap-3">
                  <div className="flex-shrink-0 w-6 h-6 rounded-full bg-desert-green text-white flex items-center justify-center text-sm font-bold">
                    1
                  </div>
                  <div>
                    <p className="font-medium text-desert-stone-dark">Pull Latest Images</p>
                    <p className="text-sm text-desert-stone">
                      Downloads the newest Docker images for all core containers
                    </p>
                  </div>
                </div>
                <div className="flex items-start gap-3">
                  <div className="flex-shrink-0 w-6 h-6 rounded-full bg-desert-green text-white flex items-center justify-center text-sm font-bold">
                    2
                  </div>
                  <div>
                    <p className="font-medium text-desert-stone-dark">Recreate Containers</p>
                    <p className="text-sm text-desert-stone">
                      Safely stops and recreates all core containers with the new images
                    </p>
                  </div>
                </div>
                <div className="flex items-start gap-3">
                  <div className="flex-shrink-0 w-6 h-6 rounded-full bg-desert-green text-white flex items-center justify-center text-sm font-bold">
                    3
                  </div>
                  <div>
                    <p className="font-medium text-desert-stone-dark">Automatic Reload</p>
                    <p className="text-sm text-desert-stone">
                      This page will automatically reload when the update is complete
                    </p>
                  </div>
                </div>
              </div>

              {isUpdating && (
                <div className="mt-6 pt-6 border-t border-desert-stone-light">
                  <StyledButton
                    variant="ghost"
                    size="sm"
                    icon="DocumentTextIcon"
                    onClick={handleViewLogs}
                    fullWidth
                  >
                    View Update Logs
                  </StyledButton>
                </div>
              )}
            </div>
          </div>
          <div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
            <Alert
              type="info"
              title="Backup Reminder"
              message="While updates are designed to be safe, it's always recommended to backup any critical data before proceeding."
              variant="solid"
            />
            <Alert
              type="warning"
              title="Temporary Downtime"
              message="Services will be briefly unavailable during the update process. This typically takes 2-5 minutes depending on your internet connection."
              variant="solid"
            />
          </div>
          {showLogs && (
            <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
              <div className="bg-white rounded-lg shadow-2xl max-w-4xl w-full max-h-[80vh] flex flex-col">
                <div className="p-6 border-b border-desert-stone-light flex justify-between items-center">
                  <h3 className="text-xl font-bold text-desert-green">Update Logs</h3>
                  <button
                    onClick={() => setShowLogs(false)}
                    className="text-desert-stone hover:text-desert-green transition-colors"
                  >
                    <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M6 18L18 6M6 6l12 12"
                      />
                    </svg>
                  </button>
                </div>
                <div className="p-6 overflow-auto flex-1">
                  <pre className="bg-black text-green-400 p-4 rounded text-xs font-mono whitespace-pre-wrap">
                    {logs || 'No logs available yet...'}
                  </pre>
                </div>
                <div className="p-6 border-t border-desert-stone-light">
                  <StyledButton variant="secondary" onClick={() => setShowLogs(false)} fullWidth>
                    Close
                  </StyledButton>
                </div>
              </div>
            </div>
          )}
        </main>
      </div>
    </SettingsLayout>
  )
}
