"use client"

import { useEffect, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { ChevronRight, Link2 } from "lucide-react"
import { Icon } from "@iconify/react"
import { DriveAddMountDialog } from "@/components/drive/drive-add-mount-dialog"
import { DriveFolderIcon } from "@/lib/drive/drive-file-icon"
import {
  DRIVE_ICON_BTN,
  DRIVE_SIDEBAR_CARET_SLOT_CLASS,
  DRIVE_SIDEBAR_ROW_BODY_CLASS,
  DRIVE_SIDEBAR_ROW_CLASS,
} from "@/lib/drive/drive-chrome-classes"
import { mailNavRowClass } from "@/lib/mail-chrome-classes"
import { cn } from "@/lib/utils"
import { displayFileName } from "@/lib/drive/display-file-name"
import { driveFolderHref, mountRootKey } from "@/lib/drive/drive-sidebar-tree"
import { useDriveMountList, useDriveMountMutations, useDriveMounts } from "@/lib/api/hooks/use-drive-queries"
import type { DriveMount } from "@/lib/api/types"
import { useIsMobile } from "@/hooks/use-mobile"
import { useDriveUIStore } from "@/lib/stores/drive-ui-store"
import { openDriveMountOAuthPopup, buildDriveMountOAuthRedirectURI } from "@/lib/drive/drive-mount-oauth"

const INDENT_PX = 16

function mountIcon(backendType: string) {
  switch (backendType) {
    case "googledrive":
    case "google":
      return "logos:google-drive"
    case "dropbox":
      return "logos:dropbox"
    case "onedrive":
    case "microsoft":
      return "logos:microsoft-onedrive"
    case "webdav":
    case "dav":
      return "mdi:cloud-sync"
    default:
      return "mdi:harddisk"
  }
}

function MountConnectButton({ mount }: { mount: DriveMount }) {
  const { fetchOAuthURL } = useDriveMountMutations()
  const [pending, setPending] = useState(false)

  if (!mount.needs_oauth && mount.status !== "pending_oauth") {
    return null
  }

  return (
    <button
      type="button"
      className={cn(
        "mr-1 flex h-7 shrink-0 cursor-pointer items-center gap-1 rounded-md px-2 text-[11px] text-primary",
        DRIVE_ICON_BTN
      )}
      disabled={pending}
      onClick={() => {
        void (async () => {
          setPending(true)
          try {
            const { oauth_url: oauthUrl } = await fetchOAuthURL(mount.id, buildDriveMountOAuthRedirectURI())
            openDriveMountOAuthPopup(oauthUrl, mount.id)
          } finally {
            setPending(false)
          }
        })()
      }}
    >
      <Link2 className="h-3.5 w-3.5" />
      {pending ? "…" : "Connecter"}
    </button>
  )
}

function MountTree({
  mount,
  active,
  pathSegments,
}: {
  mount: DriveMount
  active: boolean
  pathSegments: string[]
}) {
  const router = useRouter()
  const isMobile = useIsMobile()
  const expandedPaths = useDriveUIStore((s) => s.expandedSidebarPaths)
  const toggleSidebarPath = useDriveUIStore((s) => s.toggleSidebarPath)
  const rootKey = mountRootKey(mount.id)
  const isExpanded = expandedPaths.has(rootKey)
  const isRootSelected = active && pathSegments.length === 0
  const rootHref = driveFolderHref("mount", "/", mount.id)
  const mountReady = mount.status === "active"
  const list = useDriveMountList(mount.id, "/", 1, isExpanded && mountReady)
  const directories = list.data?.files.filter((f) => f.type === "directory") ?? []

  return (
    <div className="min-w-0">
      <div className={cn(DRIVE_SIDEBAR_ROW_CLASS, mailNavRowClass({ isSelected: isRootSelected }))}>
        <button
          type="button"
          aria-label={isExpanded ? "Replier" : "Déplier"}
          className={cn(DRIVE_SIDEBAR_CARET_SLOT_CLASS, "cursor-pointer rounded-md", DRIVE_ICON_BTN)}
          onClick={() => toggleSidebarPath(rootKey)}
          disabled={!mountReady}
        >
          <ChevronRight className={cn("h-3.5 w-3.5 text-muted-foreground transition-transform", isExpanded && "rotate-90", !mountReady && "opacity-40")} />
        </button>
        <Link
          href={rootHref}
          className={cn(DRIVE_SIDEBAR_ROW_BODY_CLASS, "cursor-pointer", !mountReady && "pointer-events-none opacity-70")}
          onClick={(event) => {
            if (!mountReady) {
              event.preventDefault()
              return
            }
            event.preventDefault()
            router.push(rootHref)
            if (isMobile) useDriveUIStore.getState().setSidebarCollapsed(true)
          }}
        >
          <Icon icon={mountIcon(mount.backend_type)} className="h-4 w-4 shrink-0" aria-hidden />
          <span className="truncate">{mount.display_name}</span>
          {mount.status === "error" ? (
            <span className="ml-auto shrink-0 text-[10px] text-destructive">!</span>
          ) : null}
        </Link>
        <MountConnectButton mount={mount} />
      </div>
      {isExpanded && mountReady
        ? directories.map((child) => (
            <MountFolderNode
              key={child.path}
              mount={mount}
              folderPath={child.path}
              depth={1}
              active={active}
              currentPath={pathSegments.length ? `/${pathSegments.join("/")}` : "/"}
            />
          ))
        : null}
    </div>
  )
}

function MountFolderNode({
  mount,
  folderPath,
  depth,
  active,
  currentPath,
}: {
  mount: DriveMount
  folderPath: string
  depth: number
  active: boolean
  currentPath: string
}) {
  const router = useRouter()
  const isMobile = useIsMobile()
  const expandedPaths = useDriveUIStore((s) => s.expandedSidebarPaths)
  const toggleSidebarPath = useDriveUIStore((s) => s.toggleSidebarPath)
  const isExpanded = expandedPaths.has(folderPath)
  const isSelected = active && currentPath === folderPath
  const href = driveFolderHref("mount", folderPath, mount.id)
  const list = useDriveMountList(mount.id, folderPath, 1, isExpanded)
  const directories = list.data?.files.filter((f) => f.type === "directory") ?? []

  return (
    <div className="min-w-0">
      <div
        className={cn(DRIVE_SIDEBAR_ROW_CLASS, mailNavRowClass({ isSelected }))}
        style={{ paddingLeft: depth * INDENT_PX }}
      >
        <button
          type="button"
          className={cn(
            DRIVE_SIDEBAR_CARET_SLOT_CLASS,
            "cursor-pointer rounded-md",
            directories.length > 0 ? DRIVE_ICON_BTN : "invisible"
          )}
          onClick={() => toggleSidebarPath(folderPath)}
        >
          <ChevronRight className={cn("h-3.5 w-3.5 text-muted-foreground transition-transform", isExpanded && "rotate-90")} />
        </button>
        <Link href={href} className={cn(DRIVE_SIDEBAR_ROW_BODY_CLASS, "cursor-pointer")} onClick={(e) => { e.preventDefault(); router.push(href); if (isMobile) useDriveUIStore.getState().setSidebarCollapsed(true) }}>
          <DriveFolderIcon file={{ path: folderPath, name: displayFileName(folderPath.split("/").pop() ?? ""), type: "directory", size: 0, mime_type: "", last_modified: "", etag: "", is_favorite: false }} size="sm" />
          <span className="truncate">{displayFileName(folderPath.split("/").pop() ?? folderPath)}</span>
        </Link>
      </div>
      {isExpanded ? directories.map((child) => (
        <MountFolderNode key={child.path} mount={mount} folderPath={child.path} depth={depth + 1} active={active} currentPath={currentPath} />
      )) : null}
    </div>
  )
}

export function DriveSidebarMounts({
  active,
  pathSegments,
  rootId,
}: {
  active: boolean
  pathSegments: string[]
  rootId: string | null
}) {
  const mounts = useDriveMounts()
  const items = mounts.data ?? []

  if (items.length === 0) {
    return null
  }

  return (
    <>
      {items.map((mount) => (
        <MountTree
          key={mount.id}
          mount={mount}
          active={active && rootId === mount.id}
          pathSegments={rootId === mount.id ? pathSegments : []}
        />
      ))}
    </>
  )
}

export function DriveConnectMountAction() {
  const [addOpen, setAddOpen] = useState(false)
  const { invalidate } = useDriveMountMutations()

  useEffect(() => {
    const onMessage = (event: MessageEvent) => {
      if (event.origin !== window.location.origin) return
      if (event.data?.type === "drive-mount-oauth-complete") {
        invalidate()
      }
    }
    window.addEventListener("message", onMessage)
    return () => window.removeEventListener("message", onMessage)
  }, [invalidate])

  return (
    <>
      <button
        type="button"
        className={cn(
          "flex w-full cursor-pointer items-center gap-2 rounded-lg border border-dashed border-border px-3 py-2 text-left text-sm text-muted-foreground transition-colors hover:bg-mail-nav-hover hover:text-foreground"
        )}
        onClick={() => setAddOpen(true)}
      >
        <span className="flex shrink-0 items-center gap-0.5" aria-hidden>
          <Icon icon="logos:google-drive" className="size-3.5" />
          <Icon icon="logos:dropbox" className="size-3.5" />
          <Icon icon="logos:microsoft-onedrive" className="size-3.5" />
        </span>
        <span className="min-w-0 truncate">Monter un volume</span>
      </button>
      <DriveAddMountDialog open={addOpen} onOpenChange={setAddOpen} />
    </>
  )
}
