import useUrlState from '@ahooksjs/use-url-state'
import { Button, Group, SegmentedControl, Stack } from '@tidbcloud/uikit'
import { ProMultiSelect, TimeRangePicker, toURLTimeRange } from '@tidbcloud/uikit/biz'
import { observer } from 'mobx-react'
import { useEffect, useMemo } from 'react'

import { HeroComponent } from 'dbaas/components/Measurement'
import { useOrgProjectClusterIds } from 'dbaas/features/Common'
import { PageShell } from 'dbaas/layouts/v5/page'
import { useCreateResourceRoleState } from 'dbaas/screens/NextGen/shared/access/create-resource-role'
import { useRegionServiceListRegions } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta2'
import { V1beta2ListRegionsRequestViewMode } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta2/interface'
import { useRegionServiceListRegions as useDedicatedRegionServiceListRegions } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1'

import { DedicatedRecycleBinList } from './DedicatedRecycleBinList'
import { EssentialRecycleBinList } from './EssentialRecycleBinList'
import { PremiumRecycleBinList } from './PremiumRecycleBinList'
import { RecycleBinEmptyState } from './RecycleBinEmptyState'
import {
  buildRegionOptions,
  normalizeArrayParam,
  PlanType,
  RecycleBinFilterProps,
  UrlStateParams,
  useDeleteTimeFilter,
  useRecycleBinPlanOptions
} from './recycleBinUtils'

const PROJECT_OWNER_ESSENTIAL_RECYCLE_BIN_MESSAGE =
  'Project Owners do not have permission to view the Recycle Bin of Essential. Please switch to an Organization Owner account to access this feature.'
const PROJECT_OWNER_DEDICATED_RECYCLE_BIN_MESSAGE =
  'Please navigate to the Project page to view the Recycle Bin contents.'

function RecycleBin() {
  const { orgId, projectId } = useOrgProjectClusterIds()
  const { ownerProjects, isOrgOwner, isAnyProjectOwner } = useCreateResourceRoleState()
  const [urlState, setUrlState] = useUrlState<UrlStateParams>({ plan: undefined }, { navigateMode: 'replace' })
  const requestedPlan = urlState.plan as PlanType | undefined
  const { planOptions, planType, isPlanOptionsLoading } = useRecycleBinPlanOptions(requestedPlan)

  useEffect(() => {
    if (!isPlanOptionsLoading && requestedPlan !== planType) {
      setUrlState({ plan: planType })
    }
  }, [isPlanOptionsLoading, planType, requestedPlan, setUrlState])

  const isDedicated = planType === 'Dedicated'
  const isPremiumOrBYOC = planType === 'Premium' || planType === 'BYOC'
  const isEssential = planType === 'Essential'
  const isEssentialV2 = planType === 'Essential_V2'
  const isOnlyProjectOwner = isAnyProjectOwner && !isOrgOwner
  const projectOwnerRecycleBinMessage =
    isOnlyProjectOwner && isEssential
      ? PROJECT_OWNER_ESSENTIAL_RECYCLE_BIN_MESSAGE
      : isOnlyProjectOwner && isDedicated
        ? PROJECT_OWNER_DEDICATED_RECYCLE_BIN_MESSAGE
        : undefined

  const setPlanType = (value: PlanType) =>
    setUrlState({ plan: value, regionIds: undefined, projectIds: undefined, from: undefined, to: undefined })

  // Filters
  const regionIds = normalizeArrayParam(urlState.regionIds)
  const projectIds = normalizeArrayParam(urlState.projectIds)
  const { timeRange, startTime, endTime } = useDeleteTimeFilter(urlState.from, urlState.to)

  // Region options (different API per plan type)
  const { data: premiumRegionData } = useRegionServiceListRegions(
    { orgId, viewMode: V1beta2ListRegionsRequestViewMode.FLAT },
    { query: { enabled: !isDedicated } }
  )
  const { data: dedicatedRegionData } = useDedicatedRegionServiceListRegions(
    { orgId, projectId, pageSize: 100 },
    { query: { enabled: isDedicated } }
  )
  const regionOptions = useMemo(
    () => buildRegionOptions(isDedicated ? dedicatedRegionData?.regions : premiumRegionData?.flatView?.regions),
    [isDedicated, premiumRegionData, dedicatedRegionData]
  )

  const projectOptions = ownerProjects.map((project) => ({
    value: project.id,
    label: project.name
  }))

  const hasActiveFilters = regionIds.length > 0 || projectIds.length > 0 || !!timeRange

  const filterProps: RecycleBinFilterProps = {
    regionIds,
    projectIds,
    startTime,
    endTime,
    hasActiveFilters
  }

  return (
    <PageShell title="Recycle Bin" headerProps={{ sticky: true, withBack: true }} bodyProps={{ pb: 60 }}>
      <Stack>
        <Group>
          <SegmentedControl value={planType} onChange={(value) => setPlanType(value as PlanType)} data={planOptions} />
          <TimeRangePicker
            value={timeRange}
            onChange={(v) => {
              const { from, to } = v ? toURLTimeRange(v) : { from: undefined, to: undefined }
              setUrlState({ from, to })
            }}
            placeholder="Select delete time range"
            clearable
            maxDateTime={() => new Date()}
          />
          <ProMultiSelect
            data={regionOptions}
            placeholder="Region"
            clearable
            width={200}
            searchable
            value={regionIds}
            onChange={(value: string[]) => setUrlState({ regionIds: value?.length ? value : undefined })}
          />
          {(isDedicated || isEssential) && (
            <ProMultiSelect
              data={projectOptions}
              placeholder="Project"
              clearable
              width={200}
              searchable
              value={projectIds}
              onChange={(value: string[]) => setUrlState({ projectIds: value?.length ? value : undefined })}
            />
          )}
          {hasActiveFilters && (
            <Button
              variant="subtle"
              onClick={() =>
                setUrlState({ regionIds: undefined, projectIds: undefined, from: undefined, to: undefined })
              }
            >
              Clear Filter
            </Button>
          )}
        </Group>

        {projectOwnerRecycleBinMessage ? (
          <>
            <HeroComponent />
            <RecycleBinEmptyState message={projectOwnerRecycleBinMessage} />
          </>
        ) : (
          <>
            {isDedicated && <DedicatedRecycleBinList {...filterProps} />}
            {isPremiumOrBYOC && <PremiumRecycleBinList key={planType} planType={planType} {...filterProps} />}
            {isEssentialV2 && <PremiumRecycleBinList key={planType} planType={planType} {...filterProps} />}
            {isEssential && <EssentialRecycleBinList {...filterProps} />}
          </>
        )}
      </Stack>
    </PageShell>
  )
}

export default observer(RecycleBin)
