import {type TrailCrumb} from '@crumbs/core/schemas'
import {Stack, useLocalSearchParams, useRouter} from 'expo-router'
import {useState} from 'react'
import {Share, View} from 'react-native'

import {
  CRUMB_REORDER_ROW_HEIGHT,
  CrumbList,
  CrumbReorderRow,
} from '@/components/crumb-list'
import {ErrorState} from '@/components/error-state'
import {SyncBadge} from '@/components/sync-badge'
import {TrailBento} from '@/components/trail-bento'
import {Button} from '@/components/ui/button'
import {Card} from '@/components/ui/card'
import {DragSortList} from '@/components/ui/drag-sort-list'
import {Layout} from '@/components/ui/layout'
import {Text} from '@/components/ui/typography'
import {useCrumbReactionSheet} from '@/hooks/use-crumb-reaction-sheet'
import {useDetail} from '@/hooks/use-detail'
import {
  alertError,
  confirmDestructive,
  showActionSheet,
} from '@/lib/dialogs'
import {goBack} from '@/lib/navigation'
import {showSyncMenu} from '@/lib/sync-menu'
import {atoms as a, useTheme} from '@/sprinkles'
import {useAuth} from '@/stores/auth'
import {useSyncState} from '@/stores/outbox'
import {moveTrailCrumb} from '@/stores/trail-crumbs'
import {
  trailDetail,
  useLeaveTrail,
  useRemoveTrail,
  useSetTrailPinned,
  useTrailShareLink,
} from '@/stores/trails'

export default function TrailDetailScreen() {
  const {trailId} = useLocalSearchParams<{trailId: string}>()
  const t = useTheme()
  const router = useRouter()
  const user = useAuth((s) => s.user)
  const {
    data: trail,
    loading,
    error,
    retry,
  } = useDetail(trailDetail, trailId)
  const leave = useLeaveTrail()
  const shareLink = useTrailShareLink()
  const setPinned = useSetTrailPinned()
  const remove = useRemoveTrail()
  const syncState = useSyncState(trailId)
  const [reordering, setReordering] = useState(false)
  const [dragActive, setDragActive] = useState(false)

  // surface a failed offline trail write, never silently: retry from
  // scratch, or discard it — the shared menu confirms, and leaves the screen
  // only when the discard removed the trail itself (a dead create)
  const onSyncBadgePress = () =>
    showSyncMenu(trailId, {onEntityDiscarded: goBack})

  const viewerRole = trail?.viewerRole

  const canRemoveCrumb = (crumb: TrailCrumb) =>
    viewerRole === 'owner' ||
    (viewerRole === 'collaborator' && crumb.authorId === user?.id)

  const handleCrumbLongPress = useCrumbReactionSheet(
    trailId,
    canRemoveCrumb,
  )

  const isMember =
    viewerRole === 'owner' || viewerRole === 'collaborator'
  const pinned = trail?.pinned ?? false

  const shareJoinLink = async () => {
    try {
      const url = await shareLink(trailId)
      await Share.share({url})
    } catch (err) {
      alertError(err)
    }
  }

  const confirmDelete = async () => {
    const ok = await confirmDestructive({
      title: 'Delete trail?',
      message: 'This trail will be permanently removed for everyone.',
      actionLabel: 'Delete',
    })
    if (ok) void remove(trailId).then(goBack)
  }

  const canReorder = isMember && (trail?.crumbs.length ?? 0) > 1

  const showTrailMenu = () =>
    showActionSheet([
      {label: 'Share join link', onPress: () => void shareJoinLink()},
      {
        label: pinned ? 'Unpin trail' : 'Pin trail',
        onPress: () => void setPinned(trailId, !pinned),
      },
      ...(canReorder
        ? [
            {
              label: 'Reorder crumbs',
              onPress: () => setReordering(true),
            },
          ]
        : []),
      ...(viewerRole === 'owner'
        ? [
            {
              label: 'Edit trail',
              onPress: () => router.push(`/trail/edit/${trailId}`),
            },
            {
              label: 'Delete trail',
              destructive: true,
              onPress: () => void confirmDelete(),
            },
          ]
        : []),
    ])

  const handleLeave = async () => {
    const ok = await confirmDestructive({
      title: 'Leave trail',
      message:
        'You will no longer see this trail or be able to add to it.',
      actionLabel: 'Leave',
    })
    if (ok) void leave(trailId).then(goBack)
  }

  return (
    <>
      <Stack.Screen options={{title: trail?.name ?? 'Trail'}} />
      {isMember && (
        <Stack.Toolbar placement="right">
          {reordering ? (
            <Stack.Toolbar.Button
              accessibilityLabel="Done reordering"
              icon="checkmark"
              onPress={() => setReordering(false)}
            />
          ) : (
            <Stack.Toolbar.Button
              accessibilityLabel="Invite"
              icon="person.badge.plus"
              onPress={() => router.push(`/trail/invite/${trailId}`)}
            />
          )}
          {!reordering && (
            <Stack.Toolbar.Button
              accessibilityLabel="Trail options"
              icon="ellipsis"
              onPress={showTrailMenu}
            />
          )}
        </Stack.Toolbar>
      )}
      <Layout.ModalContent scrollEnabled={!dragActive}>
        <Layout.Column>
          {trail && <TrailBento trail={trail} isMember={isMember} />}

          <SyncBadge
            scope={trailId}
            onPress={
              syncState === 'failed' ? onSyncBadgePress : undefined
            }
          />

          <View style={a.gap_xs}>
            {trail && viewerRole !== 'owner' && (
              <Text style={t.atoms.text_contrast_medium}>
                Shared by @{trail.authorHandle}
              </Text>
            )}
            <Card>
              {error && !trail ? (
                <ErrorState message={error} onRetry={retry} />
              ) : reordering && trail ? (
                <View style={a.py_sm}>
                  <DragSortList
                    items={trail.crumbs}
                    rowHeight={CRUMB_REORDER_ROW_HEIGHT}
                    onMove={(crumb, index) =>
                      void moveTrailCrumb(trailId, crumb.id, index)
                    }
                    onDragActiveChange={setDragActive}
                    renderItem={(crumb) => (
                      <CrumbReorderRow crumb={crumb} />
                    )}
                  />
                </View>
              ) : (
                <CrumbList
                  crumbs={trail?.crumbs ?? []}
                  loading={loading}
                  emptyMessage="This trail is empty"
                  onCrumbLongPress={
                    isMember ? handleCrumbLongPress : undefined
                  }
                />
              )}
            </Card>
          </View>

          {viewerRole === 'collaborator' && (
            <Button
              label="Leave trail"
              variant="ghost"
              color="negative"
              onPress={handleLeave}
            />
          )}
        </Layout.Column>
      </Layout.ModalContent>
    </>
  )
}
