'use client'

import * as React from 'react'
import { SvgCheckCircle } from '@chainlink/blocks-icons'
import { useIsMobile } from '../../hooks'
import { cn } from '../../utils'
import { Button, buttonVariants } from '../Button'
import { LoadingSpinner } from '../Input/icons'
import { MobileMenuSheetContent } from '../PageHeader/MobileMenuSheetContent'
import { Popover, PopoverContent, PopoverTrigger } from '../Popover'
import { Sheet, SheetTrigger } from '../Sheet'
import { Tag } from '../Tag'
import { Typography } from '../Typography'

const padding = 'px-4 py-6 md:px-6 md:py-6'

const ConnectWalletModeContext = React.createContext<'popover' | 'sheet'>(
  'popover',
)

const ConnectWalletModal = (
  props: React.ComponentPropsWithoutRef<typeof Popover> & {
    defaultOpen?: boolean
  },
) => {
  const isMobile = useIsMobile()
  const mode = isMobile ? 'sheet' : 'popover'
  const Root = isMobile ? Sheet : Popover
  const { defaultOpen = false, children, ...rest } = props
  return (
    <ConnectWalletModeContext.Provider value={mode}>
      <Root key={mode} defaultOpen={defaultOpen} {...rest}>
        {children}
      </Root>
    </ConnectWalletModeContext.Provider>
  )
}

type ConnectWalletModalTriggerProps = React.ComponentPropsWithoutRef<
  typeof PopoverTrigger
> &
  Pick<
    React.ComponentPropsWithoutRef<typeof Button>,
    'variant' | 'size' | 'width' | 'loading'
  >

const ConnectWalletModalTrigger = ({
  className,
  children,
  variant = 'primary',
  size = 'default',
  width = 'responsive',
  loading = false,
  ...props
}: ConnectWalletModalTriggerProps) => {
  const mode = React.useContext(ConnectWalletModeContext)
  return mode === 'sheet' ? (
    <SheetTrigger
      key="sheet-trigger"
      className={cn(
        buttonVariants({ variant, size, width, loading }),
        className,
      )}
      disabled={loading || props.disabled}
      {...props}
    >
      {children}
    </SheetTrigger>
  ) : (
    <PopoverTrigger
      key="popover-trigger"
      className={cn(
        buttonVariants({ variant, size, width, loading }),
        className,
      )}
      disabled={loading || props.disabled}
      {...props}
    >
      {children}
    </PopoverTrigger>
  )
}
ConnectWalletModalTrigger.displayName = 'ConnectWalletModalTrigger'

type ConnectWalletModalContentProps = React.ComponentPropsWithoutRef<
  typeof PopoverContent
> & {
  ref?: React.Ref<React.ElementRef<typeof PopoverContent>>
}

const ConnectWalletModalContent = ({
  className,
  children,
  side = 'bottom',
  align = 'end',
  sideOffset = 8,
  ...props
}: ConnectWalletModalContentProps) => {
  const mode = React.useContext(ConnectWalletModeContext)
  if (mode === 'sheet') {
    return (
      <MobileMenuSheetContent
        key="sheet-content"
        className={cn('p-0', className)}
        {...props}
      >
        {children}
      </MobileMenuSheetContent>
    )
  }
  return (
    <PopoverContent
      key="popover-content"
      side={side}
      align={align}
      sideOffset={sideOffset}
      className={cn(
        'z-50 w-fit min-w-[280px] max-w-[360px] rounded-md border border-border bg-background p-0 shadow-md outline-none',
        className,
      )}
      {...props}
    >
      {children}
    </PopoverContent>
  )
}
ConnectWalletModalContent.displayName = 'ConnectWalletModalContent'

type SelectionProps = React.HTMLAttributes<HTMLDivElement> & {
  isSelected?: boolean
  isLoading?: boolean
  ref?: React.Ref<HTMLDivElement>
}
const ConnectWalletModalSelection = ({
  className,
  children,
  isSelected,
  isLoading,
  ref,
  ...props
}: SelectionProps) => {
  const childrenArray = React.Children.toArray(children)
  const childIndicatesSelected = childrenArray.some(
    (child) =>
      React.isValidElement<SelectionProps>(child) && child.props?.isSelected,
  )
  const childIndicatesLoading = childrenArray.some(
    (child) =>
      React.isValidElement<SelectionProps>(child) && child.props?.isLoading,
  )
  const finalIsSelected = isSelected ?? childIndicatesSelected
  const finalIsLoading = isLoading ?? childIndicatesLoading
  return (
    <div
      ref={ref}
      data-state={
        finalIsLoading ? 'loading' : finalIsSelected ? 'selected' : undefined
      }
      className={cn('group', className, padding, 'pt-0')}
      {...props}
    >
      <div className="flex flex-col gap-2">{children}</div>
    </div>
  )
}
ConnectWalletModalSelection.displayName = 'ConnectWalletModalSelection'

type ConnectWalletModalHeaderProps = React.HTMLAttributes<HTMLDivElement> & {
  ref?: React.Ref<HTMLDivElement>
}

const ConnectWalletModalHeader = ({
  className,
  children,
  ref,
  ...props
}: ConnectWalletModalHeaderProps) => {
  const mode = React.useContext(ConnectWalletModeContext)

  return (
    <div
      ref={ref}
      className={cn(
        'flex flex-col space-y-1.5',
        padding,
        mode === 'sheet' ? 'py-2' : '',
        className,
      )}
      {...props}
    >
      <Typography variant="h5" color="foreground">
        {children}
      </Typography>
    </div>
  )
}
ConnectWalletModalHeader.displayName = 'ConnectWalletModalHeader'

type ConnectWalletModalDisclaimerProps =
  React.HTMLAttributes<HTMLDivElement> & {
    ref?: React.Ref<HTMLDivElement>
  }

const ConnectWalletModalDisclaimer = ({
  className,
  children,
  ref,
  ...props
}: ConnectWalletModalDisclaimerProps) => {
  return (
    <div className={cn('flex justify-center px-4 pb-4 pt-0')}>
      <div
        ref={ref}
        className={cn('mx-auto max-w-72 text-center md:max-w-none', className)}
        {...props}
      >
        <Typography variant="body-s" color="muted-more">
          {children}
        </Typography>
      </div>
    </div>
  )
}
ConnectWalletModalDisclaimer.displayName = 'ConnectWalletModalDisclaimer'

type ConnectWalletModalSelectionItemProps = React.ComponentPropsWithoutRef<
  typeof Button
> & {
  state?:
    | 'default'
    | 'detected'
    | 'recent'
    | 'disabled'
    | 'loading'
    | 'selected'
  // Base64 string, usually svg/png
  walletIcon?: string
  isSelected?: boolean
  isLoading?: boolean
  onSelect?: () => void
  ref?: React.Ref<React.ElementRef<typeof Button>>
}
const ConnectWalletModalSelectionItem = ({
  state = 'default',
  walletIcon = '',
  className,
  children,
  onSelect,
  isSelected,
  isLoading,
  ref,
  ...props
}: ConnectWalletModalSelectionItemProps) => {
  const resolvedState = isLoading ? 'loading' : isSelected ? 'selected' : state
  return (
    <Button
      ref={ref}
      variant="ghost"
      className={cn(
        'max-h-none w-full min-w-0 max-w-none items-center justify-between rounded-sm border border-transparent bg-background-alt px-4 py-4 transition-colors md:w-full md:max-w-none',
        // Dim siblings when parent has selection/loading (parent uses data-state)
        'group-data-[state=loading]:opacity-50 group-data-[state=selected]:opacity-50',
        // Keep active visible and add border accent
        'group-data-[state=loading]:data-[state=loading]:opacity-100 group-data-[state=selected]:data-[state=selected]:opacity-100 group-data-[state=loading]:data-[state=loading]:ring-1 group-data-[state=selected]:data-[state=selected]:ring-1 group-data-[state=loading]:data-[state=loading]:ring-border-active group-data-[state=selected]:data-[state=selected]:ring-border-active',
        // Disabled styling
        'data-[state=disabled]:cursor-not-allowed data-[state=disabled]:opacity-50',
        className,
      )}
      data-state={resolvedState}
      disabled={resolvedState === 'disabled' || props.disabled}
      onClick={onSelect}
      {...props}
    >
      <div className="flex w-full items-center gap-3 font-semibold">
        {walletIcon && (
          <img
            src={`data:image/svg+xml;base64,${walletIcon}`}
            alt="Wallet Icon"
            className="h-10 w-10"
          />
        )}
        {children}

        {resolvedState === 'detected' && (
          <Tag hideIcon size="sm" variant="default" className="ml-auto">
            Detected
          </Tag>
        )}
        {resolvedState === 'recent' && (
          <Tag hideIcon size="sm" variant="progress" className="ml-auto">
            Recent
          </Tag>
        )}
        {resolvedState === 'selected' && (
          <span className="ml-auto inline-flex h-5 w-5 items-center justify-center text-success-foreground">
            <SvgCheckCircle className="h-4 w-4" />
          </span>
        )}
        {resolvedState === 'loading' && (
          <span className="ml-auto inline-flex h-5 w-5 items-center justify-center fill-brand text-brand [&_path]:stroke-brand">
            <LoadingSpinner />
          </span>
        )}
      </div>
    </Button>
  )
}
ConnectWalletModalSelectionItem.displayName = 'ConnectWalletModalSelectionItem'

export {
  ConnectWalletModal,
  ConnectWalletModalHeader,
  ConnectWalletModalTrigger,
  ConnectWalletModalContent,
  ConnectWalletModalSelection,
  ConnectWalletModalDisclaimer,
  ConnectWalletModalSelectionItem,
}
