import { Text } from '@/aesthetics/Text';
import { font, radius, spacing, useColors } from '@/aesthetics/styles';
import { useStrings } from '@/common/hooks/useStrings';
import type {
  NutrientKey,
  Nutrition,
  NutritionDisplayMode,
  NutritionSortMode,
} from '@/types/nutrition';
import { ArrowDownUp, ChevronDown } from 'lucide-react-native';
import { useMemo, useState } from 'react';
import { Pressable, StyleSheet, View, useWindowDimensions } from 'react-native';
import { NUTRIENT_META } from '@/common/constants/nutrition';
import { getNutrientsByMode, sortNutrients } from '@/see-log/utils/nutrition';
import { NutrientTile } from './NutrientTile';

type NutrientBreakdownProps = {
  consumed: Nutrition;
  targets: Nutrition;
  displayMode: NutritionDisplayMode;
  sortMode: NutritionSortMode;
  onChangeDisplayMode: (mode: NutritionDisplayMode) => void;
  onChangeSortMode: (mode: NutritionSortMode) => void;
};

const GAP = spacing.xs;
const TILES_PER_ROW = 3;
const INITIAL_ROWS = 3;
const CARD_BORDER = 2;
const CONTAINER_PADDING = spacing.xl * 4 + CARD_BORDER;

function TileGrid({
  keys,
  consumed,
  targets,
  tileWidth,
}: {
  keys: NutrientKey[];
  consumed: Nutrition;
  targets: Nutrition;
  tileWidth: number;
}) {
  return (
    <View style={styles.grid}>
      {keys.map(k => {
        const meta = NUTRIENT_META[k];
        const consumedValue = consumed[k] ?? 0;
        const targetValue = targets[k] ?? 100;
        const pct = Math.min((consumedValue / targetValue) * 100, 100);
        return (
          <NutrientTile
            key={k}
            symbol={meta.symbol}
            label={meta.label}
            fillPct={pct}
            style={{ width: tileWidth, height: tileWidth }}
          />
        );
      })}
    </View>
  );
}

export function NutrientBreakdown({
  consumed,
  targets,
  displayMode,
  sortMode,
  onChangeDisplayMode,
  onChangeSortMode,
}: NutrientBreakdownProps) {
  const c = useColors();
  const strings = useStrings();
  const { width: screenWidth } = useWindowDimensions();
  const [expanded, setExpanded] = useState(false);
  const tileWidth = (screenWidth - CONTAINER_PADDING - GAP * (TILES_PER_ROW - 1)) / TILES_PER_ROW;

  const { level1, level2, level3 } = useMemo(() => {
    const byLevel = getNutrientsByMode(displayMode);
    return {
      level1: sortNutrients(byLevel.level1, sortMode, consumed, targets),
      level2: sortNutrients(byLevel.level2, sortMode, consumed, targets),
      level3: sortNutrients(byLevel.level3, sortMode, consumed, targets),
    };
  }, [displayMode, sortMode, consumed, targets]);

  const isNutrientsMode = displayMode === 'nutrients';
  const initialVisible = INITIAL_ROWS * TILES_PER_ROW;
  const hiddenCount =
    level1.length - initialVisible + (isNutrientsMode ? level2.length + level3.length : 0);
  const visibleLevel1 = expanded ? level1 : level1.slice(0, initialVisible);

  return (
    <View>
      <View style={[styles.modeTabs, { backgroundColor: c.tagBg }]}>
        {(['nutrients', 'usa_gov_dga'] as const).map(mode => (
          <Pressable
            key={mode}
            onPress={() => onChangeDisplayMode(mode)}
            style={[styles.modeTab, displayMode === mode && { backgroundColor: c.surface }]}
          >
            <Text
              style={[
                styles.modeTabText,
                { color: displayMode === mode ? c.text : c.tertiaryText },
              ]}
            >
              {mode === 'nutrients'
                ? strings.seeLog.nutrients
                : strings.seeLog.nutrientBreakdown.usRealFood}
            </Text>
          </Pressable>
        ))}
      </View>

      <View style={styles.sectionHeaderRow}>
        <Text style={[styles.sectionHeader, styles.firstSectionHeader, { color: c.secondaryText }]}>
          {strings.seeLog.nutrientBreakdown.important}
        </Text>
        <Pressable
          onPress={() => onChangeSortMode(sortMode === 'default' ? 'least_filled' : 'default')}
          style={({ pressed }) => [
            styles.sortButton,
            { backgroundColor: c.tagBg },
            pressed && { opacity: 0.7 },
          ]}
        >
          <ArrowDownUp size={12} color={c.secondaryText} />
          <Text style={[styles.sortButtonText, { color: c.secondaryText }]}>
            {sortMode === 'default'
              ? strings.seeLog.sorting.default
              : strings.seeLog.sorting.priority}
          </Text>
        </Pressable>
      </View>
      <View style={{ marginBottom: spacing.lg }}>
        <TileGrid
          keys={visibleLevel1}
          consumed={consumed}
          targets={targets}
          tileWidth={tileWidth}
        />
      </View>

      {expanded && isNutrientsMode && level2.length > 0 && (
        <View style={{ marginBottom: spacing.lg }}>
          <Text style={[styles.sectionHeader, { color: c.secondaryText }]}>
            {strings.seeLog.nutrientBreakdown.hardToEat}
          </Text>
          <TileGrid keys={level2} consumed={consumed} targets={targets} tileWidth={tileWidth} />
        </View>
      )}

      {expanded && isNutrientsMode && level3.length > 0 && (
        <View style={{ marginBottom: spacing.lg }}>
          <Text style={[styles.sectionHeader, { color: c.secondaryText }]}>
            {strings.seeLog.nutrientBreakdown.more}
          </Text>
          <TileGrid keys={level3} consumed={consumed} targets={targets} tileWidth={tileWidth} />
        </View>
      )}

      {hiddenCount > 0 && (
        <Pressable
          onPress={() => setExpanded(e => !e)}
          style={({ pressed }) => [styles.expandButton, pressed && { opacity: 0.7 }]}
        >
          <Text style={[styles.expandText, { color: c.secondaryText }]}>
            {expanded
              ? strings.seeLog.nutrientBreakdown.showLess
              : strings.seeLog.nutrientBreakdown.showMore(hiddenCount)}
          </Text>
          <ChevronDown
            size={14}
            color={c.secondaryText}
            style={{ transform: [{ rotate: expanded ? '180deg' : '0deg' }] }}
          />
        </Pressable>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  modeTabs: {
    flexDirection: 'row',
    padding: 3,
    borderRadius: radius.md,
    marginBottom: spacing.lg,
  },
  sectionHeaderRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: spacing.sm,
  },
  modeTab: {
    flex: 1,
    paddingVertical: spacing.sm,
    borderRadius: radius.sm,
    alignItems: 'center',
  },
  modeTabText: {
    fontSize: font.sm,
    fontWeight: '500',
  },
  grid: {
    width: '100%',
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: GAP,
  },
  expandButton: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: spacing.xs,
    marginTop: spacing.lg,
  },
  expandText: {
    fontSize: font.sm,
    fontWeight: '500',
  },
  sortButton: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: spacing.xs,
    paddingHorizontal: spacing.sm,
    paddingVertical: spacing.sm,
    borderRadius: radius.md,
  },
  sortButtonText: {
    fontSize: font.xs,
    fontWeight: '500',
  },
  sectionHeader: {
    fontSize: font.md,
    fontWeight: '600',
    marginTop: spacing.lg,
    marginBottom: spacing.sm,
  },
  firstSectionHeader: {
    marginTop: 0,
    marginBottom: 0,
  },
});
