'use client'
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogCancelButton,
  AlertDialogConfirmButton,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogTitle,
} from '@langgenius/dify-ui/alert-dialog'
import { cn } from '@langgenius/dify-ui/cn'
import { ScrollArea } from '@langgenius/dify-ui/scroll-area'
import { toast } from '@langgenius/dify-ui/toast'
import { useBoolean } from 'ahooks'
import * as React from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Divider from '@/app/components/base/divider'
import Link from '@/next/link'
import { usePathname, useSelectedLayoutSegments } from '@/next/navigation'
import { useGetInstalledApps, useUninstallApp, useUpdateAppPinStatus } from '@/service/use-explore'
import Item from './app-nav-item'
import NoApps from './no-apps'

const SideBar = () => {
  const { t } = useTranslation()
  const pathname = usePathname()
  const segments = useSelectedLayoutSegments()
  const lastSegment = segments.slice(-1)[0]
  const isDiscoverySelected = pathname === '/' || lastSegment === 'apps'
  const { data, isPending } = useGetInstalledApps()
  const installedApps = data?.installed_apps ?? []
  const { mutateAsync: uninstallApp, isPending: isUninstalling } = useUninstallApp()
  const { mutateAsync: updatePinStatus } = useUpdateAppPinStatus()

  const [isFold, { toggle: toggleIsFold }] = useBoolean(false)

  const [showConfirm, setShowConfirm] = useState(false)
  const [currId, setCurrId] = useState('')
  const handleDelete = async () => {
    const id = currId
    await uninstallApp(id)
    setShowConfirm(false)
    toast.success(t(($) => $['api.remove'], { ns: 'common' }))
  }

  const handleUpdatePinStatus = async (id: string, isPinned: boolean) => {
    await updatePinStatus({ appId: id, isPinned })
    toast.success(t(($) => $['api.success'], { ns: 'common' }))
  }

  const pinnedAppsCount = installedApps.filter(({ is_pinned }) => is_pinned).length
  const webAppsLabelId = React.useId()
  const installedAppItems = installedApps.map(
    (
      { id, is_pinned, uninstallable, app: { name, icon_type, icon, icon_url, icon_background } },
      index,
    ) => (
      <React.Fragment key={id}>
        <Item
          name={name}
          icon_type={icon_type}
          icon={icon}
          icon_background={icon_background}
          icon_url={icon_url}
          id={id}
          isSelected={lastSegment?.toLowerCase() === id}
          isPinned={is_pinned}
          togglePin={() => handleUpdatePinStatus(id, !is_pinned)}
          uninstallable={uninstallable}
          onDelete={(id) => {
            setCurrId(id)
            setShowConfirm(true)
          }}
        />
        {index === pinnedAppsCount - 1 && index !== installedApps.length - 1 && <Divider />}
      </React.Fragment>
    ),
  )

  return (
    <div
      data-folded={isFold ? 'true' : undefined}
      className={cn(
        'group/sidebar flex h-full w-fit shrink-0 cursor-pointer flex-col px-3 pt-6 sm:w-[240px]',
        isFold && 'sm:w-[56px]',
      )}
    >
      <div className={cn(isDiscoverySelected ? 'text-text-accent' : 'text-text-tertiary')}>
        <Link
          href="/"
          aria-label={isFold ? t(($) => $['sidebar.title'], { ns: 'explore' }) : undefined}
          className={cn(
            isDiscoverySelected ? 'bg-state-base-active' : 'hover:bg-state-base-hover',
            'flex h-8 w-full items-center justify-start gap-2 rounded-lg px-1',
          )}
        >
          <div className="flex size-6 shrink-0 items-center justify-center rounded-md bg-components-icon-bg-blue-solid">
            <span
              aria-hidden="true"
              className="i-ri-apps-fill size-3.5 text-components-avatar-shape-fill-stop-100"
            />
          </div>
          {!isFold && (
            <div
              className={cn(
                'truncate',
                isDiscoverySelected
                  ? 'system-sm-semibold text-components-menu-item-text-active'
                  : 'system-sm-regular text-components-menu-item-text',
              )}
            >
              {t(($) => $['sidebar.title'], { ns: 'explore' })}
            </div>
          )}
        </Link>
      </div>

      {!isPending && installedApps.length === 0 && !isFold && (
        <div className="mt-5">
          <NoApps />
        </div>
      )}

      {installedApps.length > 0 && (
        <div className="mt-5 flex min-h-0 flex-1 flex-col">
          {!isFold && (
            <p
              id={webAppsLabelId}
              className="mb-1.5 pl-2 system-xs-medium-uppercase break-all text-text-tertiary uppercase"
            >
              {t(($) => $['sidebar.webApps'], { ns: 'explore' })}
            </p>
          )}
          {!isFold ? (
            <div className="min-h-0 flex-1">
              <ScrollArea
                className="h-full"
                slotClassNames={{
                  viewport: 'overscroll-contain',
                  content: 'space-y-0.5 pr-3',
                }}
                labelledBy={webAppsLabelId}
              >
                {installedAppItems}
              </ScrollArea>
            </div>
          ) : (
            <div className="h-full min-h-0 flex-1 space-y-0.5 overflow-x-hidden overflow-y-auto">
              {installedAppItems}
            </div>
          )}
        </div>
      )}

      <div className="mt-auto flex py-3">
        <button
          type="button"
          aria-label={
            isFold
              ? t(($) => $['sidebar.expandSidebar'], { ns: 'layout' })
              : t(($) => $['sidebar.collapseSidebar'], { ns: 'layout' })
          }
          className="flex size-8 items-center justify-center rounded-lg text-text-tertiary transition-colors hover:bg-state-base-hover focus-visible:inset-ring-1 focus-visible:inset-ring-components-input-border-hover focus-visible:outline-hidden"
          onClick={toggleIsFold}
        >
          {isFold ? (
            <span aria-hidden="true" className="i-ri-expand-right-line" />
          ) : (
            <span aria-hidden="true" className="i-ri-layout-left-2-line" />
          )}
        </button>
      </div>

      <AlertDialog open={showConfirm} onOpenChange={setShowConfirm}>
        <AlertDialogContent>
          <div className="flex flex-col items-start gap-2 self-stretch px-6 pt-6 pb-4">
            <AlertDialogTitle className="w-full title-2xl-semi-bold text-text-primary">
              {t(($) => $['sidebar.delete.title'], { ns: 'explore' })}
            </AlertDialogTitle>
            <AlertDialogDescription className="w-full system-md-regular wrap-break-word whitespace-pre-wrap text-text-tertiary">
              {t(($) => $['sidebar.delete.content'], { ns: 'explore' })}
            </AlertDialogDescription>
          </div>
          <AlertDialogActions>
            <AlertDialogCancelButton disabled={isUninstalling}>
              {t(($) => $['operation.cancel'], { ns: 'common' })}
            </AlertDialogCancelButton>
            <AlertDialogConfirmButton
              loading={isUninstalling}
              disabled={isUninstalling}
              onClick={handleDelete}
            >
              {t(($) => $['operation.confirm'], { ns: 'common' })}
            </AlertDialogConfirmButton>
          </AlertDialogActions>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  )
}

export default React.memo(SideBar)
