import { Text } from '@/aesthetics/Text';
import { font, radius, shadows, spacing, useColors } from '@/aesthetics/styles';
import { useStrings } from '@/common/hooks/useStrings';
import { IngredientChips } from '@/see-log/components/IngredientChips';
import { useFoodLogPhoto } from '@/see-log/hooks/useFoodLogPhoto';
import type { BoundingBox, FoodLog, StagedFoodLog } from '@/types/foodlog';
import { X } from 'lucide-react-native';
import { useState, type ReactNode } from 'react';
import { ActivityIndicator, Image, Pressable, StyleSheet, View } from 'react-native';

type FoodLogCardProps = {
  log: FoodLog;
  onPress: () => void;
};

type StagedFoodLogCardProps = {
  staged: StagedFoodLog;
  onPress: () => void;
  onDelete: () => void;
  header?: ReactNode;
  children?: ReactNode;
};

export function FoodLogCard({ log, onPress }: FoodLogCardProps) {
  const c = useColors();
  const strings = useStrings();
  const { uri: photoUri, loading: photoLoading } = useFoodLogPhoto(log);
  const isCompleted = log.processingStatus === 'completed';
  const isFailed = log.processingStatus === 'failed';
  const displayName = !isCompleted ? (log.userInputFoodName ?? log.foodName) : log.foodName;
  const statusLabel = isFailed
    ? strings.seeLog.foodLog.needsAttention
    : log.processingStatus === 'pending_ai_food_reco'
      ? strings.seeLog.foodLog.identifying
      : log.processingStatus === 'pending_ai_nutrition_reco'
        ? strings.seeLog.foodLog.analyzing
        : '';

  return (
    <Pressable
      style={({ pressed }) => [
        styles.card,
        shadows.sm,
        { backgroundColor: c.surface, borderColor: c.borderSubtle },
        pressed && { opacity: 0.9 },
      ]}
      onPress={onPress}
    >
      {photoUri ? (
        <PhotoWithBox uri={photoUri} box={log.boundingBox} />
      ) : photoLoading ? (
        <View style={[styles.photo, styles.photoPlaceholder, { backgroundColor: c.tagBg }]}>
          <ActivityIndicator size="small" color={c.tertiaryText} />
        </View>
      ) : log.remotePhotoPath ? (
        <View style={[styles.photo, styles.photoPlaceholder, { backgroundColor: c.tagBg }]} />
      ) : null}

      <View style={styles.content}>
        <Text style={[styles.name, { color: c.text }]} numberOfLines={1}>
          {displayName}
        </Text>

        {!isCompleted && (
          <View style={styles.statusRow}>
            {!isFailed && <ActivityIndicator size="small" color={c.pending} />}
            <Text style={[styles.statusText, { color: isFailed ? c.danger : c.pending }]}>
              {statusLabel}
            </Text>
          </View>
        )}

        {log.ingredients.length > 0 && isCompleted && (
          <IngredientChips ingredients={log.ingredients} limit={4} />
        )}
      </View>
    </Pressable>
  );
}

const PHOTO_SIZE = 88;

function PhotoWithBox({ uri, box }: { uri: string; box?: BoundingBox }) {
  const [aspect, setAspect] = useState(0);
  return (
    <View style={styles.photoWrapper}>
      <Image
        source={{ uri }}
        style={styles.photo}
        onLoad={e => {
          const { width, height } = e.nativeEvent.source;
          if (height > 0) setAspect(width / height);
        }}
      />
      {box && aspect > 0 && <View style={[styles.boundingBox, coverBox(box, aspect)]} />}
    </View>
  );
}

function coverBox(box: BoundingBox, aspect: number) {
  let sx = 1,
    sy = 1,
    ox = 0,
    oy = 0;
  if (aspect > 1) {
    sx = aspect;
    ox = (aspect - 1) / 2;
  } else {
    sy = 1 / aspect;
    oy = (1 / aspect - 1) / 2;
  }
  return {
    left: (box.x * sx - ox) * PHOTO_SIZE,
    top: (box.y * sy - oy) * PHOTO_SIZE,
    width: box.width * sx * PHOTO_SIZE,
    height: box.height * sy * PHOTO_SIZE,
  };
}

export function StagedFoodLogCard({
  staged,
  onPress,
  onDelete,
  header,
  children,
}: StagedFoodLogCardProps) {
  const c = useColors();
  const strings = useStrings();
  const phase = staged.detectionPhase;
  const isDetecting = !!phase && phase !== 'streaming' && phase !== 'complete' && phase !== 'error';
  const disabled = isDetecting || staged.regeneratingIngredients;

  const phaseStrings: Partial<Record<string, string>> = {
    capturing: strings.addLog.detection.capturingPhoto,
    compressing: strings.addLog.detection.compressingPhoto,
    connecting: strings.addLog.detection.connectingServer,
    uploading: strings.addLog.detection.uploadingPhoto,
    identifying: strings.addLog.detection.identifyingFood,
    ingredients: strings.addLog.detection.studyingIngredients,
    error: strings.addLog.detection.retry,
  };
  const statusText = phase ? (phaseStrings[phase] ?? null) : null;

  return (
    <Pressable
      style={({ pressed }) => [
        styles.card,
        shadows.sm,
        { backgroundColor: c.surface, borderColor: c.borderSubtle },
        pressed && { opacity: 0.9 },
      ]}
      onPress={onPress}
      disabled={disabled}
    >
      {staged.photoUri && <PhotoWithBox uri={staged.photoUri} box={staged.boundingBox} />}

      <View style={styles.content}>
        <View style={styles.headerRow}>
          {statusText ? (
            <View style={styles.statusRow}>
              {phase !== 'error' && <ActivityIndicator size="small" color={c.pending} />}
              <Text
                style={[styles.statusText, { color: phase === 'error' ? c.danger : c.pending }]}
              >
                {statusText}
              </Text>
            </View>
          ) : header ? (
            header
          ) : (
            <Text style={[styles.name, { color: c.text }]} numberOfLines={1}>
              {staged.foodName}
            </Text>
          )}
          <Pressable style={styles.deleteButton} onPress={onDelete} hitSlop={8}>
            <X size={16} color={c.tertiaryText} />
          </Pressable>
        </View>
        {children}
      </View>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  card: {
    flexDirection: 'row',
    padding: spacing.lg,
    borderRadius: radius.lg,
    borderWidth: 1,
  },
  photoWrapper: {
    position: 'relative',
    width: PHOTO_SIZE,
    height: PHOTO_SIZE,
    borderRadius: radius.md,
    overflow: 'hidden',
    marginRight: spacing.lg,
  },
  photo: {
    width: PHOTO_SIZE,
    height: PHOTO_SIZE,
    borderRadius: radius.md,
  },
  boundingBox: {
    position: 'absolute',
    borderWidth: 2,
    borderColor: '#ffffff',
    borderRadius: 4,
  },
  photoMargin: {
    marginRight: spacing.lg,
  },
  photoPlaceholder: {
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: spacing.lg,
  },
  content: {
    flex: 1,
    justifyContent: 'center',
    gap: spacing.sm,
  },
  headerRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  name: {
    fontSize: font.lg,
    fontWeight: '600',
    flex: 1,
  },
  deleteButton: {
    padding: spacing.xs,
  },
  statusRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: spacing.sm,
  },
  statusText: {
    fontSize: font.xs,
    fontWeight: '500',
  },
});
