import { Feather } from '@expo/vector-icons'
import { Link } from 'expo-router'
import type { ComponentProps, ReactNode } from 'react'
import { Pressable } from 'react-native'
import { openBrowserAsync } from 'src/utils'
import { Group, Separator, Text, useTheme, View, XStack, YStack } from 'tamagui'
import { FootnoteText, SubheadText } from './Typography'

type IconName = ComponentProps<typeof Feather>['name']

type BaseRowProps = {
  icon?: IconName
  title: string
  description?: string
  tone?: 'default' | 'danger'
}

type InternalRow = BaseRowProps & {
  kind: 'internal'
  // `any` matches expo-router's Link href — varies with the generated route map.
  path: any
  // Optional numeric badge rendered before the chevron — mirrors the bell-tab
  // unread badge. `0` or undefined hides the pill.
  badge?: number
}

type ExternalRow = BaseRowProps & {
  kind: 'external'
  url: string
}

type ActionRow = BaseRowProps & {
  kind: 'action'
  onPress: () => void
  // Default `chevron-right` for in-app actions; pass `'external-link'` for
  // outbound destructive flows like "Delete Account" that hand off to a
  // browser tab.
  trailingIcon?: IconName
}

type ValueRow = BaseRowProps & {
  kind: 'value'
  value: string
}

export type LinkRowProps = InternalRow | ExternalRow | ActionRow | ValueRow

const pressableStyle = ({ pressed }: { pressed: boolean }) => ({
  opacity: pressed ? 0.7 : 1,
})

function RowBody({
  icon,
  title,
  description,
  tone = 'default',
  trailing,
}: BaseRowProps & { trailing: ReactNode }) {
  const theme = useTheme()
  const iconColor = tone === 'danger' ? theme.colorDanger.val : theme.color.val
  return (
    <XStack bg="$backgroundSecondary" px="$4" py="$3" gap="$3" alignItems="center">
      {icon ? <Feather name={icon} size={20} color={iconColor} /> : null}
      <YStack flex={1} gap={2}>
        <SubheadText emphasis="strong" tone={tone === 'danger' ? 'danger' : 'default'}>
          {title}
        </SubheadText>
        {description ? <FootnoteText tone="secondary">{description}</FootnoteText> : null}
      </YStack>
      {trailing}
    </XStack>
  )
}

// Single row primitive shared across the settings family. Geometry matches
// the cross-cutting "Settings / link-list rows" convention: leading icon, a
// `SubheadText emphasis="strong"` title, an optional `FootnoteText` description,
// and a kind-driven trailing slot (chevron / external-link / static value).
//
// Wrap a list of rows under a `<LinkRowGroup>` to get the standard section-
// header + bordered-group treatment.
export function LinkRow(row: LinkRowProps) {
  const theme = useTheme()
  const trailingIconColor = theme.colorTertiary.val

  if (row.kind === 'internal') {
    const badgeCount = row.badge && row.badge > 0 ? row.badge : 0
    return (
      <Group.Item>
        <Link href={row.path} prefetch asChild>
          <Pressable style={pressableStyle}>
            <RowBody
              icon={row.icon}
              title={row.title}
              description={row.description}
              tone={row.tone}
              trailing={
                <XStack alignItems="center" gap="$2">
                  {badgeCount > 0 ? <CountBadge count={badgeCount} /> : null}
                  <Feather name="chevron-right" size={16} color={trailingIconColor} />
                </XStack>
              }
            />
          </Pressable>
        </Link>
      </Group.Item>
    )
  }

  if (row.kind === 'external') {
    return (
      <Group.Item>
        <Pressable onPress={() => openBrowserAsync(row.url)} style={pressableStyle}>
          <RowBody
            icon={row.icon}
            title={row.title}
            description={row.description}
            tone={row.tone}
            trailing={
              <Feather name="external-link" size={16} color={trailingIconColor} />
            }
          />
        </Pressable>
      </Group.Item>
    )
  }

  if (row.kind === 'action') {
    const trailingIcon = row.trailingIcon ?? 'chevron-right'
    return (
      <Group.Item>
        <Pressable onPress={row.onPress} style={pressableStyle}>
          <RowBody
            icon={row.icon}
            title={row.title}
            description={row.description}
            tone={row.tone}
            trailing={<Feather name={trailingIcon} size={16} color={trailingIconColor} />}
          />
        </Pressable>
      </Group.Item>
    )
  }

  return (
    <Group.Item>
      <RowBody
        icon={row.icon}
        title={row.title}
        description={row.description}
        tone={row.tone}
        trailing={<FootnoteText tone="tertiary">{row.value}</FootnoteText>}
      />
    </Group.Item>
  )
}

function CountBadge({ count }: { count: number }) {
  const theme = useTheme()
  const label = count >= 40 ? '40+' : String(count)
  return (
    <View
      borderRadius={999}
      backgroundColor={theme.accent.val as string}
      minWidth={20}
      height={20}
      paddingHorizontal={6}
      justifyContent="center"
      alignItems="center"
      accessible={false}
    >
      <Text
        color={theme.onAccent.val as string}
        fontSize={11}
        fontWeight="700"
        allowFontScaling={false}
        lineHeight={13}
      >
        {label}
      </Text>
    </View>
  )
}

function rowKey(row: LinkRowProps): string {
  if (row.kind === 'external') return row.url
  if (row.kind === 'internal') return String(row.path)
  return row.title
}

// Section wrapper for a list of LinkRow children. Renders an uppercase
// `FootnoteText` header (omit by leaving `header` undefined for unlabelled
// groups like Legal), then a `<Group orientation="vertical">` with separators
// between rows so the corner-clipping carries the row backgrounds. Padding
// matches the cross-cutting convention (`px="$5" pt="$5" gap="$3"`); the
// caller can stack multiple groups vertically and the rhythm stays correct.
export function LinkRowGroup({
  header,
  rows,
}: {
  header?: string
  rows: LinkRowProps[]
}) {
  const theme = useTheme()
  if (rows.length === 0) return null
  return (
    <YStack px="$5" pt="$5" gap="$3">
      {header ? (
        <FootnoteText tone="tertiary" letterSpacing={0.4} textTransform="uppercase">
          {header}
        </FootnoteText>
      ) : null}
      <Group orientation="vertical">
        {rows.map((row, i) => (
          <View key={`${header ?? 'group'}:${rowKey(row)}`}>
            {i > 0 ? <Separator borderColor={theme.borderColor.val} /> : null}
            <LinkRow {...row} />
          </View>
        ))}
      </Group>
    </YStack>
  )
}
