import {
  Button,
  Card,
  Descriptions,
  Empty,
  Result,
  Select,
  Skeleton,
  Tabs,
  Tag,
  Typography
} from 'antd'
import { useEffect, useMemo, useRef, useState } from 'react'

import { useAgentServiceListAgents } from 'apiClient/services/agent-gateway'

import Projects, { ProjectsHandle } from './Projects'
import Routes from './Routes'
import Secrets from './Secrets'
import { formatProvider, selectInitialAgent, sortAgents } from './utils'

import './index.less'

export default function Agents() {
  const [selectedAgentId, setSelectedAgentId] = useState<string>()
  const [activeTab, setActiveTab] = useState('projects')
  const [browserWidth, setBrowserWidth] = useState(320)
  const projectsRef = useRef<ProjectsHandle>(null)

  const afterDirtyCheck = (action: () => void) => {
    if (activeTab === 'projects' && projectsRef.current) {
      projectsRef.current.beforeLeave(action)
    } else {
      action()
    }
  }

  const {
    data: agentsResponse,
    isLoading: agentsLoading,
    isError: agentsError,
    refetch: refetchAgents
  } = useAgentServiceListAgents({
    query: { retry: false }
  })

  const agents = useMemo(
    () => sortAgents(agentsResponse?.data.agents || []),
    [agentsResponse]
  )
  const selectedAgent = agents.find(
    (agent) => agent.agentId === selectedAgentId
  )

  useEffect(() => {
    if (!agents.length) {
      setSelectedAgentId(undefined)
      return
    }

    setSelectedAgentId((currentAgentId) => {
      if (agents.some((agent) => agent.agentId === currentAgentId)) {
        return currentAgentId
      }
      return selectInitialAgent(agents)?.agentId
    })
  }, [agents])

  if (agentsLoading) {
    return <Skeleton active />
  }
  if (agentsError) {
    return (
      <Result
        status="error"
        title="Agent instances are unavailable"
        subTitle="The Agent list could not be loaded."
        extra={
          <Button type="primary" onClick={() => void refetchAgents()}>
            Retry
          </Button>
        }
      />
    )
  }

  return (
    <div className="agents-page">
      <header className="agents-page-header">
        <div>
          <Typography.Title level={3}>Agents</Typography.Title>
          <Typography.Paragraph type="secondary">
            Manage resources for an Agent instance.
          </Typography.Paragraph>
        </div>
        {!!agents.length && (
          <div className="agents-agent-control">
            <Typography.Text strong>Agent Instance</Typography.Text>
            <Select
              aria-label="Agent instance"
              className="agents-agent-selector"
              optionLabelProp="value"
              value={selectedAgentId}
              onSelect={(agentId: string) =>
                afterDirtyCheck(() => {
                  setSelectedAgentId(agentId)
                })
              }
            >
              {agents.map((agent) => (
                <Select.Option key={agent.agentId} value={agent.agentId!}>
                  <span className="agents-agent-option">
                    <span>
                      <Typography.Text strong>{agent.agentId}</Typography.Text>
                      <Typography.Text type="secondary">
                        {formatProvider(agent.provider)}
                      </Typography.Text>
                    </span>
                    <span>
                      {agent.isDefault && <Tag>Default</Tag>}
                      <Tag
                        color={
                          agent.projectManagementEnabled ? 'blue' : undefined
                        }
                      >
                        {agent.projectManagementEnabled
                          ? 'Managed'
                          : 'Not managed'}
                      </Tag>
                    </span>
                  </span>
                </Select.Option>
              ))}
            </Select>
          </div>
        )}
      </header>

      {selectedAgent && (
        <Card className="agents-agent-source">
          <Descriptions bordered column={4} size="small">
            <Descriptions.Item label="Agent ID">
              {selectedAgent.agentId}
            </Descriptions.Item>
            <Descriptions.Item label="Provider">
              {formatProvider(selectedAgent.provider)}
            </Descriptions.Item>
            <Descriptions.Item label="Default">
              {selectedAgent.isDefault ? 'Yes' : 'No'}
            </Descriptions.Item>
            <Descriptions.Item label="Project management">
              {selectedAgent.projectManagementEnabled
                ? 'Managed'
                : 'Not managed'}
            </Descriptions.Item>
          </Descriptions>
        </Card>
      )}

      {!agents.length ? (
        <Empty
          description={
            <span>
              No Agent instances configured
              <br />
              <Typography.Text type="secondary">
                Agent instances will appear here after they are configured.
              </Typography.Text>
            </span>
          }
        />
      ) : selectedAgent ? (
        <Tabs
          activeKey={activeTab}
          onChange={(key) => afterDirtyCheck(() => setActiveTab(key))}
        >
          <Tabs.TabPane key="projects" tab="Projects">
            <Projects
              key={selectedAgent.agentId}
              ref={projectsRef}
              agent={selectedAgent}
              browserWidth={browserWidth}
              onBrowserWidthChange={setBrowserWidth}
            />
          </Tabs.TabPane>
          <Tabs.TabPane key="routes" tab="Routes">
            <Routes
              key={selectedAgent.agentId}
              active={activeTab === 'routes'}
              agent={selectedAgent}
            />
          </Tabs.TabPane>
          <Tabs.TabPane key="secrets" tab="Secrets">
            <Secrets
              key={selectedAgent.agentId}
              active={activeTab === 'secrets'}
              agent={selectedAgent}
            />
          </Tabs.TabPane>
        </Tabs>
      ) : null}
    </div>
  )
}
