import {View} from 'react-native'

import {AuthGate} from '@/components/auth-gate'
import {Button} from '@/components/ui/button'
import {Card} from '@/components/ui/card'
import {Divider} from '@/components/ui/divider'
import {Layout} from '@/components/ui/layout'
import {Text} from '@/components/ui/typography'
import {useOffline} from '@/lib/network'
import {type OutboxEntry} from '@/lib/outbox'
import {
  confirmDiscardMutation,
  outboxKindTitle,
} from '@/lib/sync-menu'
import {atoms as a, useTheme} from '@/sprinkles'
import {
  redriveAll,
  redriveMutation,
  useFailedCount,
  useOutboxEntries,
} from '@/stores/outbox'

const Row = ({entry}: {entry: OutboxEntry}) => {
  const t = useTheme()
  const offline = useOffline()
  const failed = !!entry.dead
  // rows render identical button pairs; the subject disambiguates them
  // for voiceover
  const subject = entry.label ?? outboxKindTitle(entry.kind)
  return (
    <View style={[a.py_md, a.gap_xs]}>
      <View
        style={[
          a.flex_row,
          a.align_center,
          a.justify_between,
          a.gap_sm,
        ]}
      >
        <View style={a.flex_1}>
          <Text style={a.font_medium}>
            {outboxKindTitle(entry.kind)}
          </Text>
          {entry.label ? (
            <Text
              emoji
              numberOfLines={1}
              style={[a.text_sm, t.atoms.text_contrast_medium]}
            >
              {entry.label}
            </Text>
          ) : null}
        </View>
        {failed && (
          <View style={[a.flex_row, a.gap_xs]}>
            <Button
              label="Discard"
              accessibilityLabel={`Discard ${subject}`}
              variant="ghost"
              color="negative"
              size="small"
              onPress={() => void confirmDiscardMutation(entry.id)}
            />
            <Button
              label="Retry"
              accessibilityLabel={`Retry ${subject}`}
              color="primary"
              size="small"
              onPress={() => redriveMutation(entry.id)}
            />
          </View>
        )}
      </View>
      <Text
        style={[
          a.text_sm,
          failed
            ? {color: t.palette.negative_600}
            : t.atoms.text_contrast_medium,
        ]}
      >
        {failed
          ? (entry.lastError ?? "Couldn't sync")
          : offline
            ? 'Waiting for connection'
            : 'Syncing…'}
      </Text>
    </View>
  )
}

export default function PendingChangesScreen() {
  return (
    <AuthGate>
      <PendingChangesScreenInner />
    </AuthGate>
  )
}

function PendingChangesScreenInner() {
  const entries = useOutboxEntries()
  const failedCount = useFailedCount()
  const t = useTheme()

  return (
    <>
      <Layout.Content>
        {entries.length === 0 ? (
          <Layout.Center>
            <Text style={t.atoms.text_contrast_medium}>
              {"Everything's synced"}
            </Text>
          </Layout.Center>
        ) : (
          <View style={a.gap_md}>
            <Text
              style={[
                a.text_sm,
                t.atoms.text_contrast_medium,
                a.pt_md,
              ]}
            >
              {
                "Changes you make offline sync automatically when you're back online."
              }
            </Text>
            <Card>
              {entries.map((entry, index) => (
                <View key={entry.id}>
                  {index > 0 && <Divider />}
                  <Row entry={entry} />
                </View>
              ))}
            </Card>
            {failedCount > 0 && (
              <Button
                label="Retry all"
                onPress={redriveAll}
                color="primary"
                size="large"
                shape="rectangular"
              />
            )}
          </View>
        )}
      </Layout.Content>
    </>
  )
}
