import { useState, useEffect } from 'react';
import { Helmet } from 'react-helmet-async';
import { useTranslation } from 'react-i18next';
import { motion, AnimatePresence } from 'framer-motion';
import { useNavigate } from 'react-router-dom';
import { loadFamilyData } from '@/lib/familyService';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Progress } from '@/components/ui/progress';
import { supabase } from '@/integrations/supabase/client';
import { format, isToday, isYesterday, parseISO } from 'date-fns';
import { fr, de, es, it, pt, pl, ja, ar, zhCN, enUS, type Locale } from 'date-fns/locale';
import { translateMissionTitle } from '@/lib/missionI18n';

const DATE_LOCALES: Record<string, Locale> = {
  en: enUS, fr, de, es, it, pt, pl, ja, ar, 'zh-CN': zhCN,
};
const getDateLocale = (lang: string) => DATE_LOCALES[lang] || DATE_LOCALES[lang.split('-')[0]] || enUS;
import { PROGRAMS, assessPerformance, getPerformanceMessage, getProgramLevel } from '@/lib/programs';
import { CheckCircle2, Bell, Flame, ChevronDown, Sparkles, Heart, TrendingUp, Shield, ArrowUpCircle } from 'lucide-react';
import ParentBottomNav from '@/components/ParentBottomNav';
import NotificationConsent from '@/components/NotificationConsent';
import ParentSignupNudge from '@/components/ParentSignupNudge';
import { WeeklyProgressChart } from '@/components/WeeklyProgressChart';
import ProgramProgressMap from '@/components/ProgramProgressMap';
import ParentStreakWidget from '@/components/ParentStreakWidget';
import ParentDashboardSkeleton from '@/components/skeletons/ParentDashboardSkeleton';
import { getCachedFamilyData, getCachedFamilyDataAge, FAMILY_STALE_MS, primeFamilyData, invalidateFamilyData, getCachedPrograms, primePrograms } from '@/lib/familyPrefetch';
import { useDelayedFlag } from '@/hooks/useDelayedFlag';


// Mix of warm encouragement + research-backed stats. Rotates daily so parents
// see fresh proof + reassurance instead of the same line every day.
const ENCOURAGEMENTS = [
  { emoji: '📈', text: "83% of families see real improvement in their child's routines within the first 2 weeks." },
  { emoji: '🌟', text: "Every small step today builds a bigger tomorrow. You're doing great!" },
  { emoji: '🧠', text: "Kids who complete a daily routine 5 days a week show 40% better focus at school." },
  { emoji: '💛', text: "Parenting is a journey, not a sprint. Be proud of what you're building." },
  { emoji: '🔁', text: "It takes ~21 days for a habit to stick. Each validation today moves you closer." },
  { emoji: '🤗', text: "Your consistency matters more than perfection. Keep showing up!" },
  { emoji: '🏆', text: "9 out of 10 parents say their child became more autonomous after 30 days on Stell." },
  { emoji: '🌈', text: "Progress isn't always visible — but it's always happening." },
  { emoji: '🛡️', text: "Children with a structured morning routine have 30% fewer meltdowns by noon." },
  { emoji: '💬', text: "Validating a mission only takes 3 seconds — but the confidence boost lasts all day." },
  { emoji: '🧘', text: "Co-regulation works: when you stay calm, your child's nervous system settles too." },
  { emoji: '🚀', text: "Families who validate daily build streaks 4× longer than those who skip days." },
];

// ── Mission-domain → parent coaching tips for habit formation ──
const DOMAIN_TIPS: Record<string, { emoji: string; category: string; tips: { tip: string; source: string }[] }> = {
  hygiene: {
    emoji: '🧼', category: 'Hygiene habits',
    tips: [
      { tip: "Don't remind — ask: 'What's the next step in your routine?' This shifts ownership to your child and builds automaticity.", source: "BJ Fogg, Tiny Habits (2019)" },
      { tip: "Do the hygiene task alongside your child at first. Mirror neurons make co-doing 3× more effective than instructing.", source: "Rizzolatti & Craighero, 2004" },
      { tip: "Celebrate immediately after completion: a high-five within 3 seconds locks in the habit loop.", source: "Crone & Steinbeis, 2024" },
      { tip: "Anchor hygiene to something they already love: 'Brush teeth → then storytime.' The reward becomes the glue.", source: "Habit Stacking — James Clear" },
    ],
  },
  nutrition: {
    emoji: '🥗', category: 'Eating habits',
    tips: [
      { tip: "Serve the new food next to a favorite — proximity reduces neophobia. Don't comment on whether they eat it.", source: "Wardle et al., 2003" },
      { tip: "Eat the same food yourself and show enjoyment. Children mirror parental eating behavior 70% of the time.", source: "Birch & Fisher, 1998" },
      { tip: "Never use 'just try one bite' as pressure. Instead: 'It's there if you want it.' Autonomy reduces food anxiety.", source: "Ellyn Satter, Division of Responsibility" },
      { tip: "Involve your child in meal prep — kids who help cook are 2× more likely to try the dish.", source: "van der Horst, 2012" },
    ],
  },
  movement: {
    emoji: '🏃', category: 'Physical activity',
    tips: [
      { tip: "Join the movement task! Parent-child physical play releases oxytocin and makes exercise a bonding ritual.", source: "Feldman, 2012" },
      { tip: "Schedule movement right before a focus task. 20 min of exercise boosts attention for the next 2 hours.", source: "Hillman et al., 2009" },
      { tip: "Outdoors > indoors: nature-based movement reduces cortisol 30% more than indoor exercise.", source: "Kuo & Taylor, 2004" },
      { tip: "Don't use exercise as punishment or obligation. Frame it as play: 'Let's see who can jump higher!'", source: "Self-Determination Theory" },
    ],
  },
  focus: {
    emoji: '🎯', category: 'Focus & attention',
    tips: [
      { tip: "Remove distractions before the task, not during. Proactive environment design beats reactive discipline.", source: "Diamond & Ling, 2020" },
      { tip: "Use a visible timer (not verbal countdowns). Externalizing time helps children manage it independently.", source: "Barkley, 2015" },
      { tip: "After focus time, allow 5 min of free choice. The brain consolidates learning during unstructured breaks.", source: "Immordino-Yang et al., 2012" },
      { tip: "Praise the process ('You really concentrated!') not the result. This builds a growth mindset for hard tasks.", source: "Dweck, 2006" },
    ],
  },
  social: {
    emoji: '🤝', category: 'Social skills',
    tips: [
      { tip: "Role-play the social scenario beforehand. Rehearsal reduces anxiety and builds a 'script' the child can draw on.", source: "Carol Gray, Social Stories" },
      { tip: "After the social task, ask 'How did it feel?' not 'Did you do it?' Emotional reflection builds empathy circuits.", source: "Siegel & Bryson, 2012" },
      { tip: "Model the exact behavior yourself first: say 'thank you' to the child before expecting them to say it to others.", source: "Bandura, Social Learning Theory" },
      { tip: "Don't force social interaction. Parallel play (side-by-side activities) builds connection at the child's pace.", source: "Dr. Barry Prizant" },
    ],
  },
  autonomy: {
    emoji: '💪', category: 'Independence',
    tips: [
      { tip: "Resist the urge to help. Wait 10 seconds longer than feels comfortable — that pause builds self-efficacy.", source: "Bandura, 1997" },
      { tip: "When they struggle, narrate what you see: 'You're working hard on that.' This validates effort over outcome.", source: "Gottman Institute" },
      { tip: "Offer two choices, not open-ended freedom: 'Red shirt or blue shirt?' Bounded autonomy prevents overwhelm.", source: "Self-Determination Theory" },
      { tip: "After they complete the task independently, say: 'You did that all by yourself!' — this cements the identity shift.", source: "James Clear, Atomic Habits" },
    ],
  },
  calm: {
    emoji: '🧘', category: 'Emotional regulation',
    tips: [
      { tip: "Co-regulate first: your calm nervous system soothes theirs. Deep breathe together, not just them.", source: "Porges, Polyvagal Theory" },
      { tip: "Never say 'calm down.' Instead: 'I'm here. Let's breathe together.' Validation before correction.", source: "Dr. Mona Delahooke" },
      { tip: "Create a 'calm corner' with soft textures, not as punishment but as a tool they choose to use.", source: "Sensory Processing Research" },
      { tip: "After a calm moment, label what happened: 'You were upset, then you took breaths, and you felt better.' This builds metacognition.", source: "Siegel, 2012" },
    ],
  },
  routine: {
    emoji: '📋', category: 'Daily routines',
    tips: [
      { tip: "Post a visual checklist at eye level. Children who see their routine complete it 40% more consistently.", source: "CHADD Research" },
      { tip: "Give a 5-minute warning before transitions. Predictability reduces tantrums by 30%.", source: "AAP Guidelines" },
      { tip: "Same order, same time, every day. The brain automates sequences after 21-66 days of consistency.", source: "Lally et al., 2010" },
      { tip: "Let your child check off tasks themselves. The physical act of marking 'done' triggers a dopamine micro-reward.", source: "Neuropsychology of Completion" },
    ],
  },
  'oral-care': {
    emoji: '🦷', category: 'Oral care',
    tips: [
      { tip: "Brush together side by side. Kids who see parents brush daily are 2× more likely to maintain the habit.", source: "AAPD Guidelines" },
      { tip: "Use a 2-minute song or timer — it makes the duration feel like a game instead of a chore.", source: "Behavioral Pediatrics" },
      { tip: "Let them choose their toothbrush color/character. Ownership of tools increases routine compliance.", source: "Self-Determination Theory" },
      { tip: "Never say 'you have to' — try 'your teeth are ready for their cleaning!' Personification works with young kids.", source: "Developmental Psychology" },
    ],
  },
};

// Fallback general tips when no domain matches
const GENERAL_PARENTING_TIPS = [
  { emoji: '🧠', category: 'Brain science', tip: "The 5:1 ratio: for every correction, offer 5 positive interactions. This builds trust and cooperation.", source: "Gottman Research" },
  { emoji: '💬', category: 'Communication', tip: "Name emotions out loud: 'You seem frustrated.' This develops emotional vocabulary 2× faster.", source: "Gottman Institute" },
  { emoji: '🤗', category: 'Connection', tip: "15 minutes of undivided attention daily reduces behavioral issues by up to 50%.", source: "PCIT Research" },
  { emoji: '🌙', category: 'Sleep', tip: "A consistent bedtime routine helps children fall asleep 20 min faster and sleep 1 hour longer.", source: "Mindell et al., 2015" },
  { emoji: '🫶', category: 'Repair', tip: "Repair after conflict matters more than avoiding it. 'I'm sorry, I got frustrated' models emotional maturity.", source: "Siegel & Bryson" },
  { emoji: '🎨', category: 'Play', tip: "Unstructured play develops executive function skills that predict success better than IQ.", source: "Yogman et al., 2018" },
];

const ADHD_OVERLAY_TIPS = [
  { emoji: '⚡', category: 'ADHD coaching', tip: "For today's missions: break each one into 2 micro-steps and celebrate after each. ADHD brains need frequent wins.", source: "Barkley, 2015" },
  { emoji: '🎵', category: 'ADHD coaching', tip: "Put on background music during tasks. Rhythmic cues improve ADHD focus by up to 25%.", source: "Zentall, 2005" },
  { emoji: '💛', category: 'ADHD coaching', tip: "ADHD kids get 20,000+ more negative messages by age 10. Today, try replacing every 'stop' with a 'start' (what TO do).", source: "Dodson, 2020" },
];

const ASD_OVERLAY_TIPS = [
  { emoji: '🗓️', category: 'ASD coaching', tip: "Before today's missions, show your child the visual order. Knowing 'what's next' reduces anxiety by 40%.", source: "Hume et al., 2014" },
  { emoji: '⏳', category: 'ASD coaching', tip: "Wait 10 seconds after giving an instruction. Autistic children often need extra processing time — silence is support.", source: "NAS Guidelines" },
  { emoji: '🧩', category: 'ASD coaching', tip: "Connect today's task to a special interest: 'Let's brush teeth like astronauts preparing for space!' Interest = motivation.", source: "Autism Research" },
];

interface DailyCoachTip {
  emoji: string;
  category: string;
  categoryKey?: string;
  tip: string;
  tipKey?: string;
  source: string;
  missionContext?: string;
}

// ── Program → tip domain (from DOMAIN_TIPS) ──
// Ensures the parent's daily tip aligns with the program their eldest child is doing.
const PROGRAM_TIP_DOMAIN: Record<string, keyof typeof DOMAIN_TIPS> = {
  'morning-ready': 'routine',
  'healthy-eating': 'nutrition',
  'oral-care': 'oral-care',
  'kind-helper': 'social',
  'bedtime-pro': 'routine',
  'active-body': 'movement',
  'focus-learning': 'focus',
  'screen-balance': 'calm',
  'emotions-calm': 'calm',
  'social-skills': 'social',
  'independence': 'autonomy',
};

/**
 * Program-aware coaching tip — uses the eldest child's primary active program
 * (the one with the highest level) to drive which DOMAIN_TIPS bucket to surface.
 * Falls back to mission-aware logic, then to general tips.
 */
function getProgramAwareTip(
  children: any[],
  childPrograms: Record<string, Record<string, number>>
): DailyCoachTip {
  const day = new Date().getDate();

  // Pick the eldest child
  const eldest = [...children].sort((a, b) => (b.age || 0) - (a.age || 0))[0];
  if (!eldest) return GENERAL_PARENTING_TIPS[day % GENERAL_PARENTING_TIPS.length];

  // Find their primary program (highest level → most invested)
  const programs = childPrograms[eldest.id] || {};
  const programIds = Object.keys(programs);
  let primaryProgramId: string | null = null;
  if (programIds.length > 0) {
    primaryProgramId = programIds.reduce((best, id) =>
      (programs[id] || 0) > (programs[best] || 0) ? id : best
    , programIds[0]);
  }

  if (primaryProgramId) {
    const domainKey = PROGRAM_TIP_DOMAIN[primaryProgramId];
    const domainData = domainKey ? DOMAIN_TIPS[domainKey] : null;
    const program = PROGRAMS.find(p => p.id === primaryProgramId);
    if (domainData && program) {
      const tipIdx = day % domainData.tips.length;
      const selected = domainData.tips[tipIdx];
      return {
        emoji: program.emoji,
        category: program.title,
        categoryKey: `programs.${program.id}.title`,
        tip: selected.tip,
        tipKey: `${domainKey}.${tipIdx}`,
        source: selected.source,
        missionContext: `__ALIGNED__${eldest.name}__${program.id}`,
      };
    }
  }

  // Fallback: original mission-aware logic
  return getMissionAwareTip(children);
}



function getMissionAwareTip(children: any[]): DailyCoachTip {
  const day = new Date().getDate();
  const hasADHD = children.some((c: any) => c.special_mode === 'tdah');
  const hasASD = children.some((c: any) => c.special_mode === 'tsa');

  // Collect today's active mission domains
  const activeDomains: string[] = [];
  const activeMissionTitles: string[] = [];
  children.forEach((c: any) => {
    (c.missions || [])
      .filter((m: any) => m.status === 'active' || m.status === 'awaiting_validation')
      .forEach((m: any) => {
        if (m.difficulty) {
          // Use domain hints from mission data
        }
        activeMissionTitles.push(m.title);
        // Infer domain from emoji
        const e = m.emoji;
        if ('🦷🧼🚿🪥'.includes(e)) activeDomains.push('oral-care');
        else if ('🍎🥕💧🥦🥗🍌🥛'.includes(e)) activeDomains.push('nutrition');
        else if ('💃🏃🌳⚽🚴🏊🧗'.includes(e)) activeDomains.push('movement');
        else if ('📖✏️🧩📐🔬🎯'.includes(e)) activeDomains.push('focus');
        else if ('🤗🗣️👋🤝😊'.includes(e)) activeDomains.push('social');
        else if ('👕🛏️👟🎒🍽️'.includes(e)) activeDomains.push('autonomy');
        else if ('🧘😤🌬️'.includes(e)) activeDomains.push('calm');
        else if ('👟📋⏰🔔'.includes(e)) activeDomains.push('routine');
        else activeDomains.push('routine');
      });
  });

  // Deduplicate domains
  const uniqueDomains = [...new Set(activeDomains)];

  // Every 3rd day, show a neurodivergence-specific overlay tip
  if (hasADHD && day % 3 === 0) {
    const idx = day % ADHD_OVERLAY_TIPS.length;
    const t = ADHD_OVERLAY_TIPS[idx];
    return { ...t, categoryKey: 'adhd', tipKey: `adhd.${idx}`, missionContext: activeMissionTitles.length > 0 ? `__RELATED__${activeMissionTitles.length}` : undefined };
  }
  if (hasASD && day % 3 === 1) {
    const idx = day % ASD_OVERLAY_TIPS.length;
    const t = ASD_OVERLAY_TIPS[idx];
    return { ...t, categoryKey: 'asd', tipKey: `asd.${idx}`, missionContext: activeMissionTitles.length > 0 ? `__RELATED__${activeMissionTitles.length}` : undefined };
  }

  // Pick a domain-specific tip based on today's missions
  if (uniqueDomains.length > 0) {
    // Rotate through active domains by day
    const selectedDomain = uniqueDomains[day % uniqueDomains.length];
    const domainData = DOMAIN_TIPS[selectedDomain];
    if (domainData) {
      const tipIdx = day % domainData.tips.length;
      const selected = domainData.tips[tipIdx];
      // Find the matching mission title for context
      const matchingMission = activeMissionTitles[day % activeMissionTitles.length];
      return {
        emoji: domainData.emoji,
        category: domainData.category,
        categoryKey: selectedDomain,
        tip: selected.tip,
        tipKey: `${selectedDomain}.${tipIdx}`,
        source: selected.source,
        missionContext: matchingMission ? `__FOR__${matchingMission}` : undefined,
      };
    }
  }

  // Fallback to general tips
  const fallbackIdx = day % GENERAL_PARENTING_TIPS.length;
  const fallback = GENERAL_PARENTING_TIPS[fallbackIdx];
  return { ...fallback, categoryKey: 'general', tipKey: `general.${fallbackIdx}` };
}

const formatCompletedDate = (dateStr: string | null, translate: (key: string) => string, lang: string = 'en') => {
  if (!dateStr) return '';
  try {
    const date = parseISO(dateStr);
    if (isToday(date)) return translate('parentValidation.today');
    if (isYesterday(date)) return translate('parentValidation.yesterday');
    return format(date, 'EEE, MMM d', { locale: getDateLocale(lang) });
  } catch { return ''; }
};

// Cheap structural signature of the loaded family payload. Used to skip
// re-rendering the Parent Home when a background refresh returns data that
// is byte-for-byte equivalent to what's already on screen — prevents the
// momentary "old frame flash" users were seeing on revisit.
const familySignature = (d: any): string => {
  if (!d) return '';
  const parts: string[] = [d.family?.id || ''];
  (d.children || []).forEach((c: any) => {
    parts.push(`${c.id}|${c.name}|${c.avatar}|${c.stars ?? 0}|${c.diamonds ?? 0}|${c.streak ?? 0}|${c.age ?? 0}`);
    (c.missions || []).forEach((m: any) => parts.push(`${m.id}:${m.status}:${m.validated_at || ''}`));
  });
  return parts.join('~');
};


const ParentDashboard = () => {
  const { t, i18n } = useTranslation();
  const navigate = useNavigate();
  // Hydrate synchronously from the prefetch cache (warmed by ProfilePicker
  // or a previous visit) — skips the skeleton on intra-app navigation.
  const cachedFamily = typeof window !== 'undefined' ? getCachedFamilyData() : null;
  const [familyData, setFamilyData] = useState<any>(cachedFamily);
  const [loading, setLoading] = useState(!cachedFamily);
  const [validating, setValidating] = useState<string | null>(null);
  const [selectedDifficulty, setSelectedDifficulty] = useState<Record<string, string>>({});
  const [expandedValidation, setExpandedValidation] = useState<string | null>(null);
  const [childPrograms, setChildPrograms] = useState<Record<string, Record<string, number>>>(() => getCachedPrograms() ?? {});
  const [levelUpCelebration, setLevelUpCelebration] = useState<{ childName: string; programTitle: string; newLevel: number; emoji: string } | null>(null);
  const [showValidationGate, setShowValidationGate] = useState(false);
  const [gateValidations, setGateValidations] = useState<any[]>([]);
  const [gateExpandedId, setGateExpandedId] = useState<string | null>(null);
  const [gateDifficulty, setGateDifficulty] = useState<Record<string, string>>({});
  const [gateReviewedCount, setGateReviewedCount] = useState(0);
  const [tipLiked, setTipLiked] = useState(false);
  const [tipSaved, setTipSaved] = useState(false);
  const [showNotifConsent, setShowNotifConsent] = useState(false);
  const [showSignupNudge, setShowSignupNudge] = useState(false);
  const [isAnonUser, setIsAnonUser] = useState(false);

  useEffect(() => {
    // Use getSession() — local read, no /auth/v1/user round-trip — so the
    // Parent Home doesn't fire an extra ~200ms request on every mount.
    supabase.auth.getSession().then(({ data: { session } }) => {
      const user = session?.user;
      setIsAnonUser(!user || (user as any).is_anonymous === true);
    });
  }, []);

  // NOTE: we used to wipe Cache Storage + unregister the SW on every mount
  // here. That destroyed the route-chunk cache and forced a cold network
  // fetch of every asset on every visit — the #1 cause of the slow parent
  // home feel. The cached family payload is invalidated via
  // invalidateFamilyData() after mutations, so a forced asset wipe is
  // unnecessary.

  const maybeShowNotifConsent = () => {
    if (!familyData?.parent) return;
    if (!('Notification' in window)) return;
    if (familyData.parent.notifications_consent_seen || Notification.permission === 'granted') return;
    setTimeout(() => setShowNotifConsent(true), 400);
  };

  const maybeShowSignupNudge = () => {
    if (!isAnonUser) return false;
    if (localStorage.getItem('stell-parent-signup-nudge-seen') === 'true') return false;
    setTimeout(() => setShowSignupNudge(true), 400);
    return true;
  };


  const handleLevelUp = async (childId: string, childName: string, progId: string, currentLevel: number) => {
    const newLevel = currentLevel + 1;
    const prog = PROGRAMS.find(p => p.id === progId);
    if (!prog || newLevel > 5) return;
    
    await supabase.from('child_programs').update({ current_level: newLevel }).eq('child_id', childId).eq('program_id', progId);
    
    setLevelUpCelebration({ childName, programTitle: prog.title, newLevel, emoji: prog.emoji });
    
    // Auto-dismiss after 4 seconds
    setTimeout(() => setLevelUpCelebration(null), 4000);
    
    await reload();
  };

  const applyPendingValidations = (data: any) => {
    const pending = data.children.flatMap((c: any) =>
      (c.missions || []).filter((m: any) => m.status === 'awaiting_validation').map((m: any) => ({
        ...m, childName: c.name, childAvatar: c.avatar, childAge: c.age, child_id: c.id,
      }))
    );
    if (pending.length > 0) {
      setGateValidations(pending);
      setShowValidationGate(true);
      setGateExpandedId(pending[0]?.id || null);
    }
  };

  const loadPrograms = async (children: any[]) => {
    const childIds = children.map((c: any) => c.id);
    if (childIds.length === 0) return;
    const { data: progData } = await supabase.from('child_programs').select('*').in('child_id', childIds);
    const map: Record<string, Record<string, number>> = {};
    (progData || []).forEach((p: any) => {
      if (!map[p.child_id]) map[p.child_id] = {};
      map[p.child_id][p.program_id] = p.current_level;
    });
    setChildPrograms(map);
    primePrograms(map);
  };

  const reload = async (isInitial = false) => {
    const data = await loadFamilyData();
    if (!data) { navigate('/profiles'); return; }
    setFamilyData(data);
    primeFamilyData(data);
    setLoading(false); // paint the real frame immediately

    if (isInitial) applyPendingValidations(data);
    // Programs load in the background — they only affect a single badge
    // and shouldn't block the main dashboard from rendering.
    void loadPrograms(data.children);
  };

  // On mount: if we already have cached family data, render it instantly.
  // Only hit the network when the cache is older than FAMILY_STALE_MS, and
  // even then update React state only if the payload signature actually
  // changed — this kills the "old frames flashing through" effect on the
  // Parent Home where every revisit used to re-paint the entire dashboard.
  useEffect(() => {
    if (cachedFamily) {
      applyPendingValidations(cachedFamily);
      setLoading(false);
      const age = getCachedFamilyDataAge();
      const fresh = age <= FAMILY_STALE_MS;
      // Programs render instantly from their own cache; only refetch if
      // we have nothing cached for at least one of the children.
      const haveAllPrograms = cachedFamily.children?.every((c: any) => childPrograms[c.id]);
      if (!haveAllPrograms) void loadPrograms(cachedFamily.children);
      if (fresh) return; // trust cache, no flash
      void (async () => {
        const next = await loadFamilyData();
        if (!next) { navigate('/profiles'); return; }
        const prevSig = familySignature(cachedFamily);
        const nextSig = familySignature(next);
        primeFamilyData(next);
        if (prevSig !== nextSig) {
          setFamilyData(next);
          void loadPrograms(next.children);
        }
      })();
    } else {
      void reload(true);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [navigate]);

  // First-visit popups: show the signup nudge FIRST (for anonymous parents),
  // and only after it closes do we surface the notifications consent. If the
  // signup nudge isn't applicable, jump straight to notifications consent.
  useEffect(() => {
    if (!familyData?.parent) return;
    const queuedSignup = maybeShowSignupNudge();
    if (queuedSignup) return; // notif consent will run from the nudge's onClose
    maybeShowNotifConsent();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [familyData?.parent?.id, familyData?.parent?.notifications_consent_seen, isAnonUser]);


  // Track tip seen + load like status
  useEffect(() => {
    if (!familyData?.family?.id) return;
    const tipKey = `${new Date().toISOString().slice(0, 10)}`;
    // Mark as seen
    supabase.from('tip_interactions').upsert(
      { family_id: familyData.family.id, tip_key: tipKey, domain: 'daily', seen: true } as any,
      { onConflict: 'family_id,tip_key' }
    ).then();
    // Check if liked
    supabase.from('tip_interactions').select('liked').eq('family_id', familyData.family.id).eq('tip_key', tipKey).maybeSingle()
      .then(({ data }) => { if (data?.liked) setTipLiked(true); });
  }, [familyData?.family?.id]);

  const handleTipLike = async () => {
    if (!familyData?.family?.id) return;
    const newLiked = !tipLiked;
    setTipLiked(newLiked);
    setTipSaved(true);
    setTimeout(() => setTipSaved(false), 1500);
    const tipKey = `${new Date().toISOString().slice(0, 10)}`;
    const dailyTipData = getMissionAwareTip(familyData.children || []);
    await supabase.from('tip_interactions').upsert(
      { family_id: familyData.family.id, tip_key: tipKey, domain: dailyTipData.category || 'general', seen: true, liked: newLiked } as any,
      { onConflict: 'family_id,tip_key' }
    );
  };

  const handleGateValidate = async (mission: any, confirmed: boolean) => {
    setValidating(mission.id);
    if (confirmed) {
      const starsEarned = mission.stars_earned || 3;
      const diamondsEarned = mission.diamonds_earned || 1;
      const difficulty = gateDifficulty[mission.id] || null;
      await supabase.from('missions').update({ status: 'validated', validated_at: new Date().toISOString(), difficulty }).eq('id', mission.id);
      const { data: child } = await supabase.from('children').select('stars, diamonds').eq('id', mission.child_id).single();
      if (child) {
        await supabase.from('children').update({ stars: child.stars + starsEarned, diamonds: child.diamonds + diamondsEarned }).eq('id', mission.child_id);
      }
    } else {
      await supabase.from('missions').update({ status: 'active', completed_at: null }).eq('id', mission.id);
    }
    setValidating(null);
    setGateDifficulty(prev => { const n = { ...prev }; delete n[mission.id]; return n; });
    
    // Track reviewed count
    setGateReviewedCount(prev => prev + 1);
    
    // Remove validated mission from gate list
    setGateValidations(prev => {
      const remaining = prev.filter(m => m.id !== mission.id);
      if (remaining.length === 0) {
        // All done — dismiss gate and reload dashboard
        setShowValidationGate(false);
        reload();
      } else {
        // Auto-expand next one
        setGateExpandedId(remaining[0]?.id || null);
      }
      return remaining;
    });
  };

  const handleValidate = async (mission: any, confirmed: boolean) => {
    setValidating(mission.id);
    if (confirmed) {
      const starsEarned = mission.stars_earned || 3;
      const diamondsEarned = mission.diamonds_earned || 1;
      const difficulty = selectedDifficulty[mission.id] || null;
      await supabase.from('missions').update({ status: 'validated', validated_at: new Date().toISOString(), difficulty }).eq('id', mission.id);
      const { data: child } = await supabase.from('children').select('stars, diamonds').eq('id', mission.child_id).single();
      if (child) {
        await supabase.from('children').update({ stars: child.stars + starsEarned, diamonds: child.diamonds + diamondsEarned }).eq('id', mission.child_id);
      }
    } else {
      await supabase.from('missions').update({ status: 'active', completed_at: null }).eq('id', mission.id);
    }
    setValidating(null);
    setSelectedDifficulty(prev => { const n = { ...prev }; delete n[mission.id]; return n; });
    setExpandedValidation(null);
    await reload();
  };

  const showSkeleton = useDelayedFlag(loading || !familyData);
  if (loading || !familyData) {
    return showSkeleton ? <ParentDashboardSkeleton /> : null;
  }



  const { parent, children } = familyData;
  const isAvatarUrl = (a: string) => a?.startsWith('http');
  // Derive parent emoji from chosen role/name when DB has a generic default
  const getParentEmoji = (p: any): string => {
    const a = p?.avatar;
    if (a && a !== '👩' && a !== '👨') return a; // custom selfie/url or other emoji
    const name = (p?.name || '').toLowerCase();
    const dadHints = ['dad', 'daddy', 'papa', 'papà', 'papá', 'pai', 'tata', 'père', 'pere', 'father', 'أب', 'パパ', '爸'];
    if (dadHints.some(h => name.includes(h))) return '👨';
    return a || '👩';
  };
  const pendingValidations = children.flatMap((c: any) =>
    (c.missions || []).filter((m: any) => m.status === 'awaiting_validation').map((m: any) => ({ ...m, childName: c.name, childAvatar: c.avatar, childAge: c.age, child_id: c.id }))
  );
  const completedCount = children.reduce((acc: number, c: any) => acc + (c.missions || []).filter((m: any) => m.status === 'validated').length, 0);
  const totalCount = children.reduce((acc: number, c: any) => acc + (c.missions || []).length, 0);
  const progressPct = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0;
  const encouragementIdx = new Date().getDate() % ENCOURAGEMENTS.length;
  const encouragement = ENCOURAGEMENTS[encouragementIdx];
  const dailyTip = getProgramAwareTip(children, childPrograms);

  // ── Validation Gate — shown first on login when tasks are pending ──
  if (showValidationGate && gateValidations.length > 0) {
    const byChild: Record<string, any[]> = {};
    gateValidations.forEach((v: any) => { const key = v.child_id; if (!byChild[key]) byChild[key] = []; byChild[key].push(v); });

    // Date context
    const todayStr = format(new Date(), 'EEEE, MMMM d', { locale: getDateLocale(i18n.language) });
    const hasOlderMissions = gateValidations.some((v: any) => v.completed_at && !isToday(parseISO(v.completed_at)));

    return (
      <div className="min-h-screen flex flex-col" style={{ background: '#235390' }}>
        {/* Dot pattern */}
        <div className="absolute inset-0 pointer-events-none opacity-[0.04]"
          style={{ backgroundImage: 'radial-gradient(circle, white 1px, transparent 1px)', backgroundSize: '24px 24px' }} />

        <div className="flex-1 px-5 md:px-8 pt-6 pb-6 max-w-lg md:max-w-2xl mx-auto w-full relative z-10">
          {/* Big hero header */}
          <motion.div initial={{ opacity: 0, y: -15 }} animate={{ opacity: 1, y: 0 }} className="text-center mb-5">
            <motion.div
              animate={{ y: [0, -8, 0], rotate: [0, 5, -5, 0] }}
              transition={{ duration: 2, repeat: Infinity, ease: 'easeInOut' }}
              className="text-6xl mb-3 inline-block"
            >📋</motion.div>
            <h1 className="text-2xl font-black text-white mb-1 leading-tight px-2">
              {t('parentValidation.gateTitle')}
            </h1>
            <p className="text-sm font-bold text-white/70">
              {t(gateValidations.length === 1 ? 'parentValidation.gateSubtitle_one' : 'parentValidation.gateSubtitle_other')} · {todayStr}
            </p>
          </motion.div>

          {/* Summary banner */}
          <motion.div 
            initial={{ opacity: 0, scale: 0.95 }} 
            animate={{ opacity: 1, scale: 1 }}
            transition={{ delay: 0.15 }}
            className="rounded-2xl border-3 border-white/20 mb-5 overflow-hidden"
            style={{ background: 'rgba(255,255,255,0.1)', boxShadow: '0 4px 0 0 rgba(0,0,0,0.15)' }}
          >
            <div className="px-4 py-3 flex items-center justify-between">
              <div className="flex items-center gap-3">
                <motion.div
                  animate={{ scale: [1, 1.15, 1] }}
                  transition={{ duration: 1.5, repeat: Infinity }}
                  className="w-12 h-12 rounded-xl flex items-center justify-center border-2 border-white/20"
                  style={{ background: '#FFC800', boxShadow: '0 3px 0 0 #cca000' }}
                >
                  <span className="text-2xl">⏳</span>
                </motion.div>
                <div>
                  <p className="font-black text-white text-lg">
                    {t('parentValidation.summaryCount', { count: gateValidations.length })}
                  </p>
                  <p className="text-xs font-bold text-white/50">
                    {Object.keys(byChild).length === 1 
                      ? t('parentValidation.fromChild', { childName: gateValidations[0].childName }) 
                      : t('parentValidation.fromKids', { count: Object.keys(byChild).length })}
                    {hasOlderMissions ? ' · ' + t('parentValidation.includesEarlier') : ' · ' + t('parentValidation.completedToday')}
                  </p>
                </div>
              </div>
              {gateReviewedCount > 0 && (
                <motion.div 
                  initial={{ scale: 0 }} animate={{ scale: 1 }}
                  className="flex items-center gap-1 rounded-xl px-3 py-1.5 border-2 border-white/20"
                  style={{ background: '#58CC02', boxShadow: '0 2px 0 0 #46a302' }}
                >
                  <span className="text-sm">✓</span>
                  <span className="text-xs font-black text-white">{gateReviewedCount}</span>
                </motion.div>
              )}
            </div>
          </motion.div>

          {/* Missions grouped by child */}
          <div className="space-y-5 overflow-y-auto max-h-[55vh] pr-1">
            {Object.entries(byChild).map(([childId, missions], ci) => {
              const first = missions[0];
              return (
                <motion.div 
                  key={childId} 
                  initial={{ opacity: 0, y: 20 }} 
                  animate={{ opacity: 1, y: 0 }} 
                  transition={{ delay: 0.1 + ci * 0.08 }}
                  className="space-y-2.5"
                >
                  {/* Child header pill */}
                  <div className="flex items-center gap-2.5 mb-1">
                    <div className="w-9 h-9 rounded-full overflow-hidden shrink-0 border-3 border-white/30"
                      style={{ boxShadow: '0 2px 0 0 rgba(0,0,0,0.2)' }}>
                      {isAvatarUrl(first.childAvatar) 
                        ? <img src={first.childAvatar} alt="" className="w-full h-full object-cover" /> 
                        : <div className="w-full h-full flex items-center justify-center bg-white text-lg">{first.childAvatar}</div>}
                    </div>
                    <span className="text-sm font-black text-white">{first.childName}</span>
                    <span className="text-xs font-bold text-white/40 rounded-full px-2 py-0.5 border border-white/15 bg-white/5">
                      {t('parentValidation.pending', { count: missions.length })}
                    </span>
                  </div>

                  {/* Mission cards */}
                  {missions.map((v: any, vi: number) => {
                    const isExpanded = gateExpandedId === v.id;
                    const dateLabel = formatCompletedDate(v.completed_at, t, i18n.language);
                    const isOld = v.completed_at && !isToday(parseISO(v.completed_at));
                    return (
                      <motion.div 
                        key={v.id} 
                        initial={{ opacity: 0, x: -12 }} 
                        animate={{ opacity: 1, x: 0 }} 
                        transition={{ delay: 0.05 * vi }}
                        className="rounded-2xl border-3 border-border bg-card overflow-hidden"
                        style={{ boxShadow: '0 4px 0 0 hsl(220 14% 78%)' }}
                      >
                        <div className="flex items-center gap-3 p-3.5 cursor-pointer" onClick={() => setGateExpandedId(isExpanded ? null : v.id)}>
                          <motion.div 
                            className="w-12 h-12 rounded-xl flex items-center justify-center text-2xl shrink-0 border-2"
                            style={{ 
                              background: isExpanded ? '#58CC02' : 'hsl(var(--muted))',
                              borderColor: isExpanded ? '#46a302' : 'hsl(var(--border))',
                              boxShadow: isExpanded ? '0 3px 0 0 #46a302' : '0 2px 0 0 hsl(220 14% 82%)',
                            }}
                            animate={isExpanded ? { scale: [1, 1.1, 1] } : {}}
                            transition={{ duration: 0.3 }}
                          >
                            {v.emoji || '⭐'}
                          </motion.div>
                          <div className="flex-1 min-w-0">
                            <p className="font-black text-sm text-foreground">{translateMissionTitle(t, v.title)}</p>

                            <div className="flex items-center gap-2 mt-0.5">
                              {dateLabel && (
                                <span className={`text-[10px] font-bold px-2 py-0.5 rounded-full ${
                                  isOld 
                                    ? 'bg-duo-yellow/15 text-duo-yellow-dark border border-duo-yellow/30' 
                                    : 'bg-primary/10 text-primary border border-primary/20'
                                }`}>
                                  {isOld ? '📅 ' : '🕐 '}{dateLabel}
                                </span>
                              )}
                              {v.stars_earned && (
                                <span className="text-[10px] font-bold text-muted-foreground">+{v.stars_earned}⭐ +{v.diamonds_earned || 1}💎</span>
                              )}
                            </div>
                          </div>
                          <motion.span 
                            animate={{ rotate: isExpanded ? 180 : 0 }} 
                            className="text-muted-foreground"
                          >
                            <ChevronDown size={18} strokeWidth={3} />
                          </motion.span>
                        </div>
                        <AnimatePresence>
                          {isExpanded && (
                            <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.2 }} className="overflow-hidden">
                              <div className="px-3.5 pb-3.5 space-y-3">
                                <div className="bg-muted/40 rounded-xl p-3">
                                  <p className="text-xs font-bold text-muted-foreground mb-2.5 text-center">{t('parentValidation.howWasIt', { childName: v.childName })}</p>
                                  <div className="flex gap-2 justify-center">
                                    {[
                                      { key: 'hard', emoji: '😰', label: t('parentValidation.difficultyHard'), bg: '#FF4B4B', shadow: '#cc3c3c' },
                                      { key: 'ok', emoji: '😊', label: t('parentValidation.difficultyOk'), bg: '#FFC800', shadow: '#cca000' },
                                      { key: 'easy', emoji: '😎', label: t('parentValidation.difficultyEasy'), bg: '#58CC02', shadow: '#46a302' },
                                    ].map(d => (
                                      <motion.button key={d.key} whileTap={{ scale: 0.9, y: 3 }} onClick={() => setGateDifficulty(prev => ({ ...prev, [v.id]: d.key }))}
                                        className={`flex flex-col items-center gap-1 rounded-xl py-2.5 px-5 border-3 font-black transition-all ${
                                          gateDifficulty[v.id] === d.key ? 'text-white' : 'bg-card border-border text-foreground'
                                        }`}
                                        style={gateDifficulty[v.id] === d.key ? { 
                                          background: d.bg, 
                                          borderColor: d.shadow, 
                                          boxShadow: `0 3px 0 0 ${d.shadow}` 
                                        } : {
                                          boxShadow: '0 3px 0 0 hsl(220 14% 82%)',
                                        }}
                                      >
                                        <span className="text-2xl">{d.emoji}</span>
                                        <span className="text-[11px]">{d.label}</span>
                                      </motion.button>
                                    ))}
                                  </div>
                                </div>
                                {!gateDifficulty[v.id] && (
                                  <p className="text-[10px] text-center text-muted-foreground font-bold animate-pulse">{t('parentValidation.pickDifficulty')}</p>
                                )}
                                <div className="flex gap-2">
                                  <motion.button 
                                    whileTap={gateDifficulty[v.id] ? { scale: 0.95, y: 3 } : {}}
                                    className={`flex-1 rounded-xl h-11 font-black text-sm border-0 transition-all ${
                                      gateDifficulty[v.id] ? 'text-white' : 'text-white/50 cursor-not-allowed'
                                    }`}
                                    style={{ 
                                      background: gateDifficulty[v.id] ? '#58CC02' : '#58CC0266', 
                                      boxShadow: gateDifficulty[v.id] ? '0 4px 0 0 #46a302' : 'none' 
                                    }}
                                    disabled={validating === v.id || !gateDifficulty[v.id]} 
                                    onClick={() => handleGateValidate(v, true)}
                                  >
                                    {t('parentValidation.validateButton')}
                                  </motion.button>
                                  <motion.button 
                                    whileTap={gateDifficulty[v.id] ? { scale: 0.95, y: 3 } : {}}
                                    className={`flex-1 rounded-xl h-11 font-black text-sm border-2 transition-all ${
                                      gateDifficulty[v.id] ? 'text-foreground bg-card border-border' : 'text-muted-foreground bg-muted/50 border-border/50 cursor-not-allowed'
                                    }`}
                                    style={{ boxShadow: gateDifficulty[v.id] ? '0 4px 0 0 hsl(220 14% 78%)' : 'none' }}
                                    disabled={validating === v.id || !gateDifficulty[v.id]} 
                                    onClick={() => handleGateValidate(v, false)}
                                  >
                                    {t('parentValidation.rejectButton')}
                                  </motion.button>
                                </div>
                              </div>
                            </motion.div>
                          )}
                        </AnimatePresence>
                      </motion.div>
                    );
                  })}
                </motion.div>
              );
            })}
          </div>

          {/* Skip button */}
          <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.5 }} className="mt-6 text-center">
            <motion.button
              whileTap={{ scale: 0.95 }}
              onClick={() => { setShowValidationGate(false); reload(); }}
              className="text-sm text-white/50 hover:text-white font-bold px-5 py-2 rounded-xl border border-white/15 hover:border-white/30 transition-all"
              style={{ background: 'rgba(255,255,255,0.08)' }}
            >
              {t('parentValidation.skipButton')}
            </motion.button>
          </motion.div>
        </div>
      </div>
    );
  }

  return (
    <>
      <Helmet>
        <title>{t('seo.parent.title')}</title>
        <meta name="description" content={t('seo.parent.description')} />
        <meta property="og:title" content={t('seo.parent.title')} />
        <meta property="og:description" content={t('seo.parent.description')} />
        <meta property="og:url" content="https://star.stellkey.com/parent" />
        <link rel="canonical" href="https://star.stellkey.com/parent" />
      </Helmet>
      <div className="min-h-screen pb-24 bg-background">
      {/* Hero header */}
      <div className="border-b-2 border-border bg-card">
        <div className="px-5 pt-4 pb-3">
          <div className="max-w-2xl mx-auto">
            <div className="flex items-center justify-between mb-3">
              <div className="flex items-center gap-3.5">
                <motion.div whileTap={{ scale: 0.95 }} className="w-12 h-12 rounded-2xl bg-primary/10 flex items-center justify-center text-xl overflow-hidden border-2 border-primary/20">
                  {isAvatarUrl(parent?.avatar) ? <img src={parent.avatar} alt={parent.name} className="w-full h-full object-cover" /> : getParentEmoji(parent)}
                </motion.div>
                <div>
                  <p className="text-[11px] text-muted-foreground font-bold tracking-wide uppercase">
                    {(() => {
                      const h = new Date().getHours();
                      if (h < 12) return t('parent.greeting.morning', 'Good morning');
                      if (h < 18) return t('parent.greeting.afternoon', 'Good afternoon');
                      return t('parent.greeting.evening', 'Good evening');
                    })()}
                  </p>
                  <h1 className="text-lg font-black text-foreground tracking-tight">
                    {parent?.name || t('parent.greeting.fallbackName', 'Parent')} 💛
                  </h1>
                </div>
              </div>
            </div>

            {/* ── Parent daily streak (top of home) ── */}
            {familyData?.parent?.id && (
              <div className="mb-3">
                <ParentStreakWidget parentId={familyData.parent.id} parentName={familyData.parent.name} />
              </div>
            )}

            {/* Daily parenting coaching tip — mission-aware with like */}
            <motion.div initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }}
              className="duo-card rounded-2xl p-3 mb-3 border border-secondary/20">
              <div className="flex items-start gap-3">
                <div className="w-10 h-10 rounded-xl bg-secondary/10 border-2 border-secondary/20 flex items-center justify-center shrink-0">
                  <span className="text-lg">{dailyTip.emoji}</span>
                </div>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-0.5">
                    <span className="text-[10px] font-black uppercase tracking-wider text-secondary">{(() => {
                      const ck = dailyTip.categoryKey || 'general';
                      // Program-aware tip uses key like "programs.<id>.title"
                      if (ck.startsWith('programs.')) return t(ck, dailyTip.category);
                      return t(`coaching.category.${ck}`, dailyTip.category);
                    })()}</span>
                    <span className="text-[9px] text-muted-foreground font-bold">· {t('coaching.parentCoaching', 'Parent coaching')}</span>
                  </div>
                  <p className="text-[13px] text-foreground font-semibold leading-relaxed">{dailyTip.tipKey ? t(`coaching.tip.${dailyTip.tipKey}`, dailyTip.tip) : dailyTip.tip}</p>
                  <p className="text-[10px] text-muted-foreground mt-1.5 font-bold italic">— {dailyTip.source}</p>
                  {dailyTip.missionContext && (
                    <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.3 }}
                      className="text-[10px] text-primary font-bold mt-2 bg-primary/5 rounded-lg px-2 py-1 inline-block">
                      {(() => {
                        const mc = dailyTip.missionContext!;
                        if (mc.startsWith('__ALIGNED__')) {
                          const [, name, progId] = mc.split('__');
                          return t('parentHome.missionContextAligned', { name, program: t(`programs.${progId}.title`, progId) });
                        }
                        if (mc.startsWith('__FOR__')) {
                          return t('parentHome.missionContextFor', { title: mc.slice(7) });
                        }
                        if (mc.startsWith('__RELATED__')) {
                          const count = parseInt(mc.slice(11), 10);
                          return t('parentHome.missionContextRelated', { count });
                        }
                        return mc;
                      })()}
                    </motion.p>
                  )}
                  {/* Like button + feedback */}
                  <div className="flex items-center gap-2 mt-2.5">
                    <motion.button
                      whileTap={{ scale: 0.85 }}
                      onClick={handleTipLike}
                      className={`flex items-center gap-1 text-[10px] font-bold px-2.5 py-1 rounded-full transition-all ${
                        tipLiked
                          ? 'bg-duo-pink/15 text-duo-pink border border-duo-pink/30'
                          : 'bg-muted text-muted-foreground hover:bg-muted/80 border border-transparent'
                      }`}
                    >
                      <motion.span animate={tipLiked ? { scale: [1, 1.4, 1] } : {}} transition={{ duration: 0.3 }}>
                        {tipLiked ? '❤️' : '🤍'}
                      </motion.span>
                      {tipLiked ? t('coaching.helpfulYes', 'Helpful!') : t('coaching.helpfulAsk', 'Helpful?')}
                    </motion.button>
                    <AnimatePresence>
                      {tipSaved && (
                        <motion.span initial={{ opacity: 0, x: -5 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0 }}
                          className="text-[9px] text-primary font-bold">
                          {t('coaching.tipSaved', "✓ Saved — we'll show more like this")}
                        </motion.span>
                      )}
                    </AnimatePresence>
                  </div>
                </div>
              </div>
            </motion.div>

            {/* Weekly progress chart — celebratory family momentum */}
            <WeeklyProgressChart childIds={children.map((c: any) => c.id)} />

            {/* Encouraging message */}
            <motion.div initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.04 }}
              className="duo-card rounded-xl p-2.5 mb-3">
              <div className="flex items-start gap-2.5">
                <Heart size={16} className="text-duo-pink shrink-0 mt-0.5" strokeWidth={2.5} />
                <p className="text-xs text-foreground font-semibold leading-relaxed">{t(`coaching.encouragement.${encouragementIdx}`, encouragement.text)}</p>
              </div>
            </motion.div>

            {/* Quick stats — Duolingo 3D cards */}
            <div className="grid grid-cols-3 gap-2.5">
              <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.08 }}
                className="duo-card rounded-2xl p-3 text-center">
                <div className="flex items-center justify-center mb-1">
                  <CheckCircle2 size={18} className="text-primary" strokeWidth={2.5} />
                </div>
                <p className="text-xl font-black text-foreground">{completedCount}</p>
                <p className="text-[10px] text-muted-foreground font-bold">{t('parentValidation.validated')}</p>
              </motion.div>
              <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.12 }}
                className="duo-card rounded-2xl p-3 text-center">
                <div className="relative flex items-center justify-center mb-1">
                  <Bell size={18} className="text-secondary" strokeWidth={2.5} />
                  {gateReviewedCount > 0 && (
                    <span className="absolute -top-1.5 -right-1.5 min-w-[16px] h-4 rounded-full bg-destructive text-white text-[9px] font-black flex items-center justify-center px-1">
                      {gateReviewedCount}
                    </span>
                  )}
                </div>
                <p className="text-xl font-black text-secondary">{pendingValidations.length}</p>
                <p className="text-[10px] text-muted-foreground font-bold">{t('parentValidation.toReview')}</p>
                {gateReviewedCount > 0 && (
                  <p className="text-[9px] text-primary font-black mt-0.5">✓ {gateReviewedCount} reviewed</p>
                )}
              </motion.div>
              <motion.div initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.16 }}
                className="duo-card rounded-2xl p-3 text-center">
                <div className="flex items-center justify-center gap-1 mb-1">
                  <Flame size={18} className="text-duo-orange animate-flame-pulse" strokeWidth={2.5} />
                </div>
                <p className="text-xl font-black text-foreground">{Math.max(...children.map((c: any) => c.streak || 0), 0)}</p>
                <p className="text-[10px] text-muted-foreground font-bold">{t('parentValidation.bestStreak')}</p>
              </motion.div>
            </div>
          </div>
        </div>
      </div>

      <div className="max-w-2xl mx-auto px-4 pt-4 space-y-6">
        {/* Parent streak now lives at the top of the hero header */}

        {/* ── Pending validations ── */}
        {pendingValidations.length > 0 && (() => {
          const byChild: Record<string, any[]> = {};
          pendingValidations.forEach((v: any) => { const key = v.child_id; if (!byChild[key]) byChild[key] = []; byChild[key].push(v); });
          return (
            <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} className="space-y-5">
              <div className="flex items-center gap-2.5">
                <div className="w-8 h-8 rounded-xl bg-primary/8 flex items-center justify-center">
                  <Bell size={16} className="text-primary" strokeWidth={2} />
                </div>
                <h2 className="text-base font-bold text-foreground">{t('parentValidation.dashboardTitle')}</h2>
                <Badge variant="secondary" className="ml-auto text-xs font-bold">{pendingValidations.length}</Badge>
              </div>
              {Object.entries(byChild).map(([childId, missions]) => {
                const first = missions[0];
                return (
                  <div key={childId} className="space-y-2.5">
                    <div className="flex items-center gap-2 pl-1">
                      <div className="w-7 h-7 rounded-full overflow-hidden shrink-0 border border-border">
                        {isAvatarUrl(first.childAvatar) ? <img src={first.childAvatar} alt="" className="w-full h-full object-cover" /> : <div className="w-full h-full flex items-center justify-center bg-muted text-sm">{first.childAvatar}</div>}
                      </div>
                      <span className="text-sm font-semibold text-foreground">{first.childName}</span>
                      <span className="text-xs text-muted-foreground">· {t('parentValidation.summaryCount', { count: missions.length })}</span>
                    </div>
                    {missions.map((v: any, vi: number) => {
                      const isExpanded = expandedValidation === v.id;
                      const dateLabel = formatCompletedDate(v.completed_at, t, i18n.language);
                      return (
                        <motion.div key={v.id} initial={{ opacity: 0, x: -12 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.05 * vi }}>
                          <div className="rounded-2xl border-3 border-border bg-card overflow-hidden"
                            style={{ boxShadow: '0 4px 0 0 hsl(220 14% 78%)' }}>
                            <div className="flex items-center gap-3 p-3.5 cursor-pointer" onClick={() => setExpandedValidation(isExpanded ? null : v.id)}>
                              <motion.div 
                                className="w-12 h-12 rounded-xl flex items-center justify-center text-2xl shrink-0 border-2"
                                style={{ 
                                  background: isExpanded ? '#58CC02' : 'hsl(var(--muted))',
                                  borderColor: isExpanded ? '#46a302' : 'hsl(var(--border))',
                                  boxShadow: isExpanded ? '0 3px 0 0 #46a302' : '0 2px 0 0 hsl(220 14% 82%)',
                                }}
                                animate={isExpanded ? { scale: [1, 1.1, 1] } : {}}
                                transition={{ duration: 0.3 }}
                              >
                                {v.emoji || '⭐'}
                              </motion.div>
                              <div className="flex-1 min-w-0">
                                <p className="font-black text-sm text-foreground">{translateMissionTitle(t, v.title)}</p>
                                <div className="flex items-center gap-2 mt-0.5">
                                  {dateLabel && (
                                    <span className={`text-[10px] font-bold px-2 py-0.5 rounded-full ${
                                      v.completed_at && !isToday(parseISO(v.completed_at))
                                        ? 'bg-duo-yellow/15 text-duo-yellow-dark border border-duo-yellow/30' 
                                        : 'bg-primary/10 text-primary border border-primary/20'
                                    }`}>
                                      {v.completed_at && !isToday(parseISO(v.completed_at)) ? '📅 ' : '🕐 '}{dateLabel}
                                    </span>
                                  )}
                                  {v.stars_earned && (
                                    <span className="text-[10px] font-bold text-muted-foreground">+{v.stars_earned}⭐ +{v.diamonds_earned || 1}💎</span>
                                  )}
                                </div>
                              </div>
                              <motion.span animate={{ rotate: isExpanded ? 180 : 0 }} className="text-muted-foreground">
                                <ChevronDown size={18} strokeWidth={3} />
                              </motion.span>
                            </div>
                            <AnimatePresence>
                              {isExpanded && (
                                <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} transition={{ duration: 0.2 }} className="overflow-hidden">
                                  <div className="px-3.5 pb-3.5 space-y-3">
                                    <div className="bg-muted/40 rounded-xl p-3">
                                      <p className="text-xs font-bold text-muted-foreground mb-2.5 text-center">{t('parentValidation.howWasIt', { childName: v.childName })}</p>
                                      <div className="flex gap-2 justify-center">
                                        {[
                                          { key: 'hard', emoji: '😰', label: t('parentValidation.difficultyHard'), bg: '#FF4B4B', shadow: '#cc3c3c' },
                                          { key: 'ok', emoji: '😊', label: t('parentValidation.difficultyOk'), bg: '#FFC800', shadow: '#cca000' },
                                          { key: 'easy', emoji: '😎', label: t('parentValidation.difficultyEasy'), bg: '#58CC02', shadow: '#46a302' },
                                        ].map(d => (
                                          <motion.button key={d.key} whileTap={{ scale: 0.9, y: 3 }} onClick={() => setSelectedDifficulty(prev => ({ ...prev, [v.id]: d.key }))}
                                            className={`flex flex-col items-center gap-1 rounded-xl py-2.5 px-5 border-3 font-black transition-all ${
                                              selectedDifficulty[v.id] === d.key ? 'text-white' : 'bg-card border-border text-foreground'
                                            }`}
                                            style={selectedDifficulty[v.id] === d.key ? { 
                                              background: d.bg, 
                                              borderColor: d.shadow, 
                                              boxShadow: `0 3px 0 0 ${d.shadow}` 
                                            } : {
                                              boxShadow: '0 3px 0 0 hsl(220 14% 82%)',
                                            }}
                                          >
                                            <span className="text-2xl">{d.emoji}</span>
                                            <span className="text-[11px]">{d.label}</span>
                                          </motion.button>
                                        ))}
                                      </div>
                                    </div>
                                    {!selectedDifficulty[v.id] && (
                                      <p className="text-[10px] text-center text-muted-foreground font-bold animate-pulse">{t('parentValidation.pickDifficulty')}</p>
                                    )}
                                    <div className="flex gap-2">
                                      <motion.button 
                                        whileTap={selectedDifficulty[v.id] ? { scale: 0.95, y: 3 } : {}}
                                        className={`flex-1 rounded-xl h-11 font-black text-sm border-0 transition-all ${
                                          selectedDifficulty[v.id] ? 'text-white' : 'text-white/50 cursor-not-allowed'
                                        }`}
                                        style={{ 
                                          background: selectedDifficulty[v.id] ? '#58CC02' : '#58CC0266', 
                                          boxShadow: selectedDifficulty[v.id] ? '0 4px 0 0 #46a302' : 'none' 
                                        }}
                                        disabled={validating === v.id || !selectedDifficulty[v.id]} 
                                        onClick={() => handleValidate(v, true)}
                                      >
                                        {t('parentValidation.validateButton')}
                                      </motion.button>
                                      <motion.button 
                                        whileTap={selectedDifficulty[v.id] ? { scale: 0.95, y: 3 } : {}}
                                        className={`flex-1 rounded-xl h-11 font-black text-sm border-2 transition-all ${
                                          selectedDifficulty[v.id] ? 'text-foreground bg-card border-border' : 'text-muted-foreground bg-muted/50 border-border/50 cursor-not-allowed'
                                        }`}
                                        style={{ boxShadow: selectedDifficulty[v.id] ? '0 4px 0 0 hsl(220 14% 78%)' : 'none' }}
                                        disabled={validating === v.id || !selectedDifficulty[v.id]} 
                                        onClick={() => handleValidate(v, false)}
                                      >
                                        {t('parentValidation.rejectButton')}
                                      </motion.button>
                                    </div>
                                  </div>
                                </motion.div>
                              )}
                            </AnimatePresence>
                          </div>
                        </motion.div>
                      );
                    })}
                  </div>
                );
              })}
            </motion.div>
          );
        })()}

        {pendingValidations.length === 0 && (
          <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="duo-card rounded-2xl p-5 text-center">
            <Sparkles size={28} className="text-accent mx-auto mb-2" strokeWidth={2} />
            <p className="text-sm font-black text-foreground">{t('parentValidation.allCaughtUp')}</p>
            <p className="text-xs text-muted-foreground font-bold mt-1">{t('parentValidation.noMissions')}</p>
          </motion.div>
        )}

        {/* ── Children Performance ── */}
        <div className="flex items-center gap-3 pt-2">
          <div className="h-px flex-1 bg-border" />
          <span className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">{t('parentValidation.kidsProgress')}</span>
          <div className="h-px flex-1 bg-border" />
        </div>

        {children.map((child: any, ci: number) => {
          const childCompleted = (child.missions || []).filter((m: any) => m.status === 'validated').length;
          const childTotal = (child.missions || []).length;
          const childPct = childTotal > 0 ? Math.round((childCompleted / childTotal) * 100) : 0;
          const trend = assessPerformance(child.missions || []);
          const trendMsg = getPerformanceMessage(trend);

          return (
            <motion.div key={child.id} initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.1 + ci * 0.05 }}>
              <Card className="overflow-hidden border-2 border-border hover:border-primary/40 transition-colors" style={{ boxShadow: '0 2px 0 0 hsl(220 14% 82%)' }}>
                <CardContent className="p-0">
                  <div className="flex items-center gap-3 p-4 bg-gradient-to-r from-muted/30 to-transparent">
                    <div className="w-11 h-11 rounded-xl bg-card flex items-center justify-center text-2xl overflow-hidden border border-border shadow-sm">
                      {isAvatarUrl(child.avatar) ? <img src={child.avatar} alt={child.name} className="w-full h-full object-cover" /> : child.avatar}
                    </div>
                    <div className="flex-1">
                      <h3 className="font-bold text-sm">{child.name}</h3>
                      <p className="text-xs text-muted-foreground">{t('parentHome.childMeta', { age: child.age, level: child.level })}</p>
                    </div>
                    <div className="flex items-center gap-2">
                      {(child.streak || 0) > 0 && (
                        <div className="flex items-center gap-1 bg-primary/8 rounded-full px-2.5 py-1">
                          <Flame size={12} className="text-stell-orange animate-flame-pulse" strokeWidth={2.5} />
                          <span className="text-xs font-bold text-primary">{child.streak}</span>
                        </div>
                      )}
                      <div className="flex items-center gap-1 bg-card rounded-full px-2.5 py-1 border border-border">
                        <span className="text-xs">⭐</span>
                        <span className="text-xs font-bold">{child.stars}</span>
                      </div>
                    </div>
                  </div>

                  {/* Performance insight */}
                  <div className="px-4 py-2 bg-muted/20 border-t border-border/30">
                    <div className="flex items-center gap-2">
                      <TrendingUp size={14} className={trend === 'harder' ? 'text-accent' : trend === 'easier' ? 'text-stell-coral' : 'text-muted-foreground'} strokeWidth={2} />
                      <p className="text-xs text-foreground/90 font-medium">{t(`parentHome.perf.${trend === 'harder' ? 'harder' : trend === 'easier' ? 'easier' : 'stay'}`, trendMsg.message)}</p>
                      <Badge variant="outline" className="ml-auto text-[10px]">
                        {trend === 'harder' ? t('parentHome.badge.harder', 'Level up ↑') : trend === 'easier' ? t('parentHome.badge.easier', 'Gentle mode') : t('parentHome.badge.steady', 'Steady')}
                      </Badge>
                    </div>
                  </div>

                  {/* Active programs progress map */}
                  {childPrograms[child.id] && Object.keys(childPrograms[child.id]).length > 0 && (
                    <div className="px-4 py-2.5 border-t border-border/20 space-y-2">
                      <p className="text-[10px] font-semibold text-muted-foreground uppercase tracking-wider">{t('parentHome.progressMap', 'Progress Map')}</p>
                      {Object.entries(childPrograms[child.id]).map(([progId, currentLvl]) => {
                        const prog = PROGRAMS.find(p => p.id === progId);
                        if (!prog) return null;
                        return (
                          <ProgramProgressMap
                            key={progId}
                            program={prog}
                            currentLevel={currentLvl}
                            missions={child.missions || []}
                            onLevelUp={() => handleLevelUp(child.id, child.name, progId, currentLvl)}
                            onClick={() => navigate('/parent/chat', { state: { program: progId } })}
                          />
                        );
                      })}
                    </div>
                  )}

                  <div className="px-4 pb-3 pt-2">
                    <div className="flex gap-2 flex-wrap mb-3">
                      {(child.missions || []).map((m: any) => (
                        <div key={m.id} className={`flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium border transition-colors ${
                          m.status === 'validated' ? 'bg-accent/10 border-accent/30 text-accent'
                            : m.status === 'awaiting_validation' ? 'bg-primary/10 border-primary/30 text-primary animate-pulse'
                            : 'bg-muted/50 border-border text-muted-foreground'
                        }`}>
                          <span>{m.emoji || '⭐'}</span>
                          {m.status === 'validated' ? '✅' : m.status === 'awaiting_validation' ? '⏳' : ''}
                        </div>
                      ))}
                    </div>
                    <div className="flex items-center gap-2.5">
                      <Progress value={childPct} className="h-1.5 flex-1" />
                      <span className="text-[11px] font-semibold text-muted-foreground">{childPct}%</span>
                    </div>
                  </div>
                </CardContent>
              </Card>
            </motion.div>
          );
        })}


        {/* Overall progress */}
        <Card className="border-2 border-border" style={{ boxShadow: '0 2px 0 0 hsl(220 14% 82%)' }}>
          <CardContent className="p-4">
            <div className="flex items-center gap-2 mb-3">
              <Shield size={16} className="text-primary" strokeWidth={2} />
              <h3 className="font-bold text-sm flex-1">{t('parentHome.familyProgress', 'Family Progress')}</h3>
              <span className="text-sm font-bold text-primary">{progressPct}%</span>
            </div>
            <Progress value={progressPct} className="h-2 mb-2" />
            <p className="text-xs text-muted-foreground">
              {progressPct >= 75 ? t('parentHome.overallMsg.high') : progressPct >= 50 ? t('parentHome.overallMsg.mid') : t('parentHome.overallMsg.low')}
            </p>
          </CardContent>
        </Card>

        <p className="text-center text-xs text-muted-foreground pb-2">
          {t('parentHome.footerStat')}
        </p>
      </div>

      {/* Level Up Celebration Overlay */}
      <AnimatePresence>
        {levelUpCelebration && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm"
            onClick={() => setLevelUpCelebration(null)}
          >
            <motion.div
              initial={{ scale: 0.3, opacity: 0, y: 40 }}
              animate={{ scale: 1, opacity: 1, y: 0 }}
              exit={{ scale: 0.5, opacity: 0, y: -20 }}
              transition={{ type: 'spring', damping: 15, stiffness: 200 }}
              className="bg-card rounded-3xl p-8 mx-6 text-center shadow-2xl border border-border max-w-sm"
              onClick={(e) => e.stopPropagation()}
            >
              <motion.div
                animate={{ rotate: [0, -10, 10, -10, 0], scale: [1, 1.2, 1] }}
                transition={{ duration: 0.8, delay: 0.2 }}
                className="text-6xl mb-4"
              >
                {levelUpCelebration.emoji}
              </motion.div>
              <motion.div
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                transition={{ delay: 0.3 }}
              >
                <h2 className="text-xl font-bold text-foreground mb-1">{t('parentHome.levelUpTitle', 'Level Up! 🎉')}</h2>
                <p className="text-sm text-muted-foreground mb-3">
                  <span className="font-semibold text-foreground">{levelUpCelebration.childName}</span> {t('parentHome.reached', 'reached')}
                </p>
                <div className="inline-flex items-center gap-2 bg-accent/15 rounded-full px-4 py-2 mb-4">
                  <span className="text-lg font-bold text-accent">{t('parentHome.levelLabel', { level: levelUpCelebration.newLevel })}</span>
                  <span className="text-sm text-muted-foreground">{t('parentHome.inProgram', { program: levelUpCelebration.programTitle })}</span>
                </div>
                <div className="flex justify-center gap-1 mt-2">
                  {Array.from({ length: 8 }).map((_, i) => (
                    <motion.span
                      key={i}
                      initial={{ opacity: 0, y: 20 }}
                      animate={{ opacity: [0, 1, 0], y: [-10, -30, -50] }}
                      transition={{ delay: 0.4 + i * 0.08, duration: 1.2, repeat: Infinity, repeatDelay: 2 }}
                      className="text-lg"
                    >
                      {['⭐', '✨', '🌟', '💫', '🎊', '🏆', '🎯', '💪'][i]}
                    </motion.span>
                  ))}
                </div>
              </motion.div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>

      <ParentBottomNav />

      {showNotifConsent && familyData?.parent && (
        <NotificationConsent
          parentId={familyData.parent.id}
          familyId={familyData.family.id}
          childName={familyData?.children?.[0]?.name}
          onClose={() => setShowNotifConsent(false)}
        />
      )}

      <ParentSignupNudge
        isOpen={showSignupNudge}
        parentAvatar={getParentEmoji(familyData?.parent)}
        parentName={familyData?.parent?.name}
        childName={familyData?.children?.[0]?.name}
        familyId={familyData?.family?.id}
        parentId={familyData?.parent?.id}
        onClose={() => {
          localStorage.setItem('stell-parent-signup-nudge-seen', 'true');
          setShowSignupNudge(false);
          // Now that the signup nudge is dismissed, surface the notifications
          // consent (if still applicable for this parent).
          maybeShowNotifConsent();
        }}
      />


    </div>
    </>
  );
};

export default ParentDashboard;
