import {
  Link,
  Stack,
  useLocalSearchParams,
  useRouter,
} from 'expo-router'
import {Pressable, View} from 'react-native'

import {Attribution} from '@/components/attribution'
import {Chip} from '@/components/chip'
import {ErrorState} from '@/components/error-state'
import {ExternalLink} from '@/components/external-link'
import {LoadingState} from '@/components/loading-state'
import {RemindersSection} from '@/components/reminders-section'
import {SyncBadge} from '@/components/sync-badge'
import {TrailList} from '@/components/trail-list'
import {Button} from '@/components/ui/button'
import {Card, CardLabel} from '@/components/ui/card'
import {HeaderIconButton} from '@/components/ui/header-icon-button'
import {Layout} from '@/components/ui/layout'
import {MapPreview} from '@/components/ui/map-preview'
import {Thumbnail} from '@/components/ui/thumbnail'
import {H1, Text} from '@/components/ui/typography'
import {useDetail} from '@/hooks/use-detail'
import {addCrumbToCalendar} from '@/lib/calendar'
import {formatDateTime, formatDayDate} from '@/lib/dates'
import {confirmDestructive, showActionSheet} from '@/lib/dialogs'
import {crumbCoords, isLocated, toMarker} from '@/lib/geo'
import {hapticSuccess} from '@/lib/haptics'
import {goBack} from '@/lib/navigation'
import {showSyncMenu} from '@/lib/sync-menu'
import {atoms as a, useTheme} from '@/sprinkles'
import {useAuth} from '@/stores/auth'
import {
  crumbDetail,
  useCrumbContext,
  useRemoveCrumb,
  useUpdateCrumb,
} from '@/stores/crumbs'
import {useSyncState} from '@/stores/outbox'

export default function CrumbDetailScreen() {
  const {crumbId} = useLocalSearchParams<{crumbId: string}>()
  const t = useTheme()
  const router = useRouter()
  const user = useAuth((s) => s.user)
  const {
    data: crumb,
    loading,
    error,
    retry,
  } = useDetail(crumbDetail, crumbId)
  const context = useCrumbContext(crumbId)
  const updateCrumb = useUpdateCrumb()
  const removeCrumb = useRemoveCrumb()
  const syncState = useSyncState(crumbId)

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

  const setStatus = async (status: 'saved' | 'done') => {
    if (!crumb) return
    await updateCrumb(crumb.id, {status})
    if (status === 'done') hapticSuccess()
  }

  const confirmCancelPlan = async () => {
    if (!crumb) return
    const ok = await confirmDestructive({
      title: 'Cancel plan?',
      message: 'This crumb will no longer be planned.',
      actionLabel: 'Cancel plan',
      cancelLabel: 'Keep plan',
    })
    if (ok)
      void updateCrumb(crumb.id, {status: 'saved', plannedFor: null})
  }

  const confirmUndoDone = async () => {
    const ok = await confirmDestructive({
      title: 'Undo been here?',
      message: 'This crumb will no longer be marked as visited.',
      actionLabel: 'Undo',
    })
    if (ok) void setStatus('saved')
  }

  const confirmDelete = async () => {
    const ok = await confirmDestructive({
      title: 'Delete crumb?',
      message: 'This crumb will be permanently removed.',
      actionLabel: 'Delete',
    })
    if (ok) void removeCrumb(crumbId).then(goBack)
  }

  const showCrumbMenu = () =>
    showActionSheet([
      {
        label: 'Edit',
        onPress: () => router.push(`/crumb/edit/${crumbId}`),
      },
      {
        label: 'Delete crumb',
        destructive: true,
        onPress: () => void confirmDelete(),
      },
    ])

  if (!crumb) {
    return (
      <Layout.Screen>
        <Stack.Screen options={{title: 'Crumb'}} />
        {error ? (
          <Layout.Center>
            <ErrorState message={error} onRetry={retry} />
          </Layout.Center>
        ) : loading ? (
          <LoadingState />
        ) : null}
      </Layout.Screen>
    )
  }

  const isOwn = crumb.authorId === user?.id

  return (
    <>
      <Stack.Screen
        options={{
          title: crumb.name,
          headerRight: isOwn
            ? () => (
                <HeaderIconButton
                  icon="ellipsis"
                  label="Crumb options"
                  onPress={showCrumbMenu}
                />
              )
            : undefined,
        }}
      />
      <Layout.ModalContent contentContainerStyle={a.gap_lg}>
        {crumb.imageUrl && (
          <Thumbnail
            uri={crumb.imageUrl}
            width="100%"
            aspectRatio={16 / 9}
            radius={14}
            accessibilityLabel={crumb.name}
          />
        )}

        <H1 emoji>{crumb.name}</H1>

        {!isOwn && context?.author && (
          <Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
            Added by @{context.author.handle}
          </Text>
        )}

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

        {crumb.note && <Text emoji>{crumb.note}</Text>}

        {crumb.origin?.url && (
          <ExternalLink href={crumb.origin.url}>
            <Text style={[a.text_sm, {color: t.palette.primary_500}]}>
              View original
            </Text>
          </ExternalLink>
        )}

        {crumb.tags.length > 0 && (
          <View style={[a.flex_row, a.flex_wrap, a.gap_sm]}>
            {crumb.tags.map((tag) => (
              <Chip key={tag.name} label={tag.name} />
            ))}
          </View>
        )}

        {crumb.place && (
          <View style={a.gap_xs}>
            {crumb.place.name !== crumb.name && (
              <Text emoji style={a.text_sm}>
                {crumb.place.name}
              </Text>
            )}
            {crumb.place.address && (
              <Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
                {crumb.place.address}
              </Text>
            )}
          </View>
        )}

        {isLocated(crumb) ? (
          <Link
            href={{
              pathname: '/map',
              params: {
                lat: crumb.place.latitude,
                lng: crumb.place.longitude,
                zoom: 15,
                crumbId: crumb.id,
              },
            }}
            asChild
          >
            <Pressable accessibilityLabel="Open map">
              <MapPreview
                center={crumbCoords(crumb)}
                markers={[toMarker(crumb, t.palette.bg)]}
                zoom={15}
                height={220}
              />
            </Pressable>
          </Link>
        ) : (
          <Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
            No location
          </Text>
        )}

        {((crumb.status === 'planned' && crumb.plannedFor) ||
          crumb.event?.startsAt) && (
          <View style={[a.flex_row, a.align_center, a.gap_sm]}>
            {crumb.status === 'planned' && crumb.plannedFor ? (
              <Button
                label={`Planned for ${formatDayDate(crumb.plannedFor)}`}
                accessibilityHint="Long press to cancel plan"
                variant="ghost"
                color="secondary"
                size="small"
                shape="flush"
                onLongPress={confirmCancelPlan}
              >
                <Button.Text style={t.atoms.text_contrast_medium}>
                  Planned for {formatDayDate(crumb.plannedFor)}
                </Button.Text>
              </Button>
            ) : crumb.event?.startsAt ? (
              <Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
                On {formatDayDate(crumb.event.startsAt)}
              </Text>
            ) : null}
            <Button
              label="Add to calendar"
              variant="ghost"
              color="primary"
              size="small"
              onPress={() => void addCrumbToCalendar(crumb)}
            />
          </View>
        )}

        {context && context.trails.length > 0 && (
          <View style={a.gap_xs}>
            <CardLabel>In trails</CardLabel>
            <Card>
              <TrailList
                trails={context.trails}
                currentUserId={user?.id}
              />
            </Card>
          </View>
        )}

        {isOwn && crumb.status !== 'done' && (
          <RemindersSection crumb={crumb} />
        )}

        {isOwn && (
          <View style={a.gap_sm}>
            {crumb.status === 'done' && (
              <Button
                label="Been here"
                accessibilityHint="Long press to undo"
                variant="ghost"
                color="secondary"
                size="small"
                shape="flush"
                onLongPress={confirmUndoDone}
              >
                <View style={[a.flex_row, a.align_center, a.gap_xs]}>
                  <Text emoji style={a.text_sm}>
                    ✅
                  </Text>
                  <Button.Text style={t.atoms.text_contrast_medium}>
                    Been here
                  </Button.Text>
                </View>
              </Button>
            )}
            <View style={[a.flex_row, a.gap_sm]}>
              <Button
                label={
                  crumb.status === 'planned'
                    ? 'Replan'
                    : crumb.status === 'done'
                      ? 'Plan another visit'
                      : 'Plan it'
                }
                onPress={() => router.push(`/plan/${crumb.id}`)}
                color="secondary"
                size="large"
                shape="rectangular"
                style={a.flex_1}
              />
              {crumb.status !== 'done' && (
                <Button
                  label="Been here"
                  onPress={() => void setStatus('done')}
                  color="secondary"
                  size="large"
                  shape="rectangular"
                  style={a.flex_1}
                />
              )}
            </View>
          </View>
        )}

        {/* any crumb you can see may be filed into a trail, not only your own */}
        <Button
          label="Add to trail"
          onPress={() => router.push(`/add-to-trail/${crumb.id}`)}
          color="primary"
          size="large"
          shape="rectangular"
        />

        <Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
          {formatDateTime(crumb.createdAt)}
        </Text>

        <Attribution />
      </Layout.ModalContent>
    </>
  )
}
