import { Badge, Box, Combobox, Group, Highlight, Input, Menu, ScrollArea, Stack, Typography } from '@tidbcloud/uikit'
import { IconBuilding05, IconCheck, IconSearchMd } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useState } from 'react'

import { ORG_TYPE } from 'dbaas/features/Organization'
import { CentralUserProfileOrg, CentralUserProfileProject } from 'dbaas/services/account/interface'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { useOrgSwitch } from './useNavigationSwitch'

export const OrgProjectPanel = ({
  onClickNextLayer,
  onNavigation
}: {
  onClickNextLayer: (org: CentralUserProfileOrg, project: CentralUserProfileProject) => void
  onNavigation: (projectId: string) => void
}) => {
  const [search, setSearch] = useState('')

  return (
    <Box h={354}>
      <Stack gap={4}>
        <Input
          pr={8}
          size="sm"
          placeholder="Find organization..."
          leftSection={<IconSearchMd size={16} c="gray.9" />}
          value={search}
          onChange={(e) => setSearch(e.currentTarget.value)}
          onClick={() => {
            eventTracking('Click search organization', {
              source: 'Global Side Navbar Switcher NextGen'
            })
          }}
        />
        <ScrollArea.Autosize type="scroll" mah={430} scrollbarSize="var(--combobox-padding)" offsetScrollbars="y">
          <OrgProjectList search={search.trim()} onClickNextLayer={onClickNextLayer} onNavigation={onNavigation} />
        </ScrollArea.Autosize>
      </Stack>
    </Box>
  )
}

const OrgProjectList = observer(
  ({
    search,
    onClickNextLayer,
    onNavigation
  }: {
    search: string
    onClickNextLayer: (org: CentralUserProfileOrg, project: CentralUserProfileProject) => void
    onNavigation: (projectId: string) => void
  }) => {
    const {
      store: { userProfile, allProjects }
    } = useStores()
    const {
      store: {
        lastVisitLocation: { orgId }
      }
    } = useStores()
    const projects = useMemo(() => {
      if (!search) {
        return allProjects
      }
      return allProjects.filter((p) => p.name.toLowerCase().includes(search.toLowerCase()))
    }, [search, allProjects])
    const orgs = useMemo(() => {
      const projectsOrgMap = projects.reduce(
        (prev, cur) => {
          if (!prev[cur.org_id]) {
            prev[cur.org_id] = true
          }
          return prev
        },
        {} as { [k: string]: boolean }
      )
      return userProfile.orgs.filter((o) => projectsOrgMap[o.id] || o.name.toLowerCase().includes(search.toLowerCase()))
    }, [userProfile.orgs, projects, search])

    useEffect(() => {
      const escapeId = (value: string) => {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const esc = (globalThis as any)?.CSS?.escape
        return esc ? esc(value) : value.replace(/"/g, '\\"')
      }

      const el = document.querySelector<HTMLElement>(`[data-nav-switcher-org-id="${escapeId(orgId)}"]`)
      el?.scrollIntoView({ block: 'nearest' })
    }, [orgId, search])

    return (
      <Menu>
        {!orgs.length && (
          <Typography variant="body-lg" c="carbon.7" px={12}>
            No organization
          </Typography>
        )}
        {orgs.map((org) => {
          return (
            <OrgProjectListItem
              key={org.id}
              projects={projects}
              org={org}
              search={search}
              onClickNextLayer={onClickNextLayer}
              onNavigation={onNavigation}
            />
          )
        })}
      </Menu>
    )
  }
)

const OrgProjectListItem = observer(
  ({
    // projects,
    org,
    search,
    onClickNextLayer: _onClickNextLayer,
    onNavigation
  }: {
    projects: CentralUserProfileProject[]
    org: CentralUserProfileOrg
    search: string
    onClickNextLayer: (org: CentralUserProfileOrg, project: CentralUserProfileProject) => void
    onNavigation: (projectId: string) => void
  }) => {
    const {
      store: {
        lastVisitLocation: { orgId, projectId: _projectId }
      }
    } = useStores()
    const isOrgSelected = orgId === org.id
    const orgSwitch = useOrgSwitch()
    const isOtherOrgSwitch = orgId !== org.id

    return (
      <>
        <Combobox.Option
          key={org.id}
          value={org.id}
          data-nav-switcher-org-id={org.id}
          onClick={async () => {
            eventTracking('Organization Changed', {
              source: 'Global Side Navbar Switcher NextGen',
              isOtherOrgSwitch
            })
            onNavigation(org.id)
            orgSwitch(org)
          }}
          sx={{
            wordBreak: 'break-all'
          }}
        >
          <Group gap="xs" justify="space-between" wrap="nowrap">
            <Group gap={8} wrap="nowrap">
              <Group sx={{ flexShrink: 0 }}>
                <IconBuilding05 size={16} c="carbon.8" strokeWidth={1} />
              </Group>
              <Highlight highlight={search}>{org.name || `Org (ID: ${org.id})`}</Highlight>
              {org.org_type === ORG_TYPE.ENTERPRISE && (
                <Badge sx={{ pointerEvents: 'none', flexShrink: 0 }}>Ent.</Badge>
              )}
            </Group>
            <Group>{isOrgSelected && <IconCheck c="peacock.7" />}</Group>
          </Group>
        </Combobox.Option>
      </>
    )
  }
)
