// dashboard.jsx — BeanScriptor home screen

const TINTS = ['#F5E6D3', '#EAD7C2', '#E2CDB4', '#D9C0A4', '#EFDFC8'];

function formatDate(iso) {
  if (!iso) return '';
  const d   = new Date(iso);
  const now = new Date();
  const yes = new Date(now); yes.setDate(now.getDate() - 1);
  if (d.toDateString() === now.toDateString()) return 'Today';
  if (d.toDateString() === yes.toDateString()) return 'Yesterday';
  return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

const SCORE_STEPS = [0, 70, 75, 80, 85, 90];

function deriveScore(log) {
  if (log.cva_total_score != null) return Math.round(log.cva_total_score);
  const vals = [log.acidity, log.body, log.balance, log.sweetness].filter(v => v != null);
  if (!vals.length) return 0;
  return Math.round(vals.reduce((a, b) => a + b, 0) / vals.length * 10);
}

function mapLog(log) {
  return {
    id:      log.id,
    name:    log.coffee_name,
    roaster: log.roaster   || '—',
    method:  log.brew_method || '—',
    date:    formatDate(log.created_at),
    score:   deriveScore(log),
    tint:    TINTS[log.id % TINTS.length],
  };
}

function greeting() {
  const h = new Date().getHours();
  if (h < 12) return 'Morning';
  if (h < 18) return 'Afternoon';
  return 'Evening';
}

function Achievement({ icon, title, sub, color, locked }) {
  return (
    <div style={{
      flex: '0 0 auto', width: 116,
      background: locked ? 'rgba(36,23,18,0.04)'
                         : 'linear-gradient(180deg, rgba(255,252,246,0.95), rgba(244,232,213,0.7))',
      border: `0.5px solid ${PALETTE.hairline}`,
      borderRadius: 18,
      padding: 12,
      display: 'flex', flexDirection: 'column', gap: 8,
      backdropFilter: 'blur(10px)',
      opacity: locked ? 0.55 : 1,
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 12,
        background: locked ? 'rgba(36,23,18,0.06)' : color,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 18,
      }}>{icon}</div>
      <div>
        <div style={{ fontSize: 13, fontWeight: 700, color: PALETTE.espresso, lineHeight: 1.15 }}>{title}</div>
        <div style={{ fontSize: 11, color: PALETTE.inkMuted, marginTop: 2, lineHeight: 1.2 }}>{sub}</div>
      </div>
    </div>
  );
}

function StatPill({ label, value, accent }) {
  return (
    <div style={{
      flex: 1, padding: '10px 12px',
      borderRadius: 14,
      background: 'rgba(255,252,246,0.7)',
      border: `0.5px solid ${PALETTE.hairline}`,
      display: 'flex', flexDirection: 'column', gap: 2,
    }}>
      <div style={{ fontSize: 10, fontWeight: 600, letterSpacing: 1, textTransform: 'uppercase',
                    color: PALETTE.inkMuted }}>{label}</div>
      <div style={{ fontSize: 20, fontWeight: 700, color: accent || PALETTE.espresso,
                    fontFeatureSettings: '"tnum"', letterSpacing: -0.4 }}>{value}</div>
    </div>
  );
}

function ScoreRing({ score, size = 44 }) {
  const r = size / 2 - 3;
  const c = 2 * Math.PI * r;
  const p = score / 100;
  const tone = score >= 88 ? PALETTE.sageDeep
             : score >= 80 ? PALETTE.caramel
             : PALETTE.cocoa;
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none"
                stroke="rgba(36,23,18,0.08)" strokeWidth="3" />
        <circle cx={size/2} cy={size/2} r={r} fill="none"
                stroke={tone} strokeWidth="3" strokeLinecap="round"
                strokeDasharray={c} strokeDashoffset={c * (1 - p)} />
      </svg>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex',
        alignItems: 'center', justifyContent: 'center',
        fontSize: 13, fontWeight: 700, color: PALETTE.espresso,
        fontFeatureSettings: '"tnum"',
      }}>{score || '—'}</div>
    </div>
  );
}

function LogRow({ log, onOpen }) {
  return (
    <div onClick={onOpen} style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px',
      cursor: 'pointer',
    }}>
      <div style={{
        width: 44, height: 44, borderRadius: 14,
        background: log.tint,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flex: '0 0 auto',
      }}>
        <CoffeeBean size={22} color={PALETTE.espresso} tilt={-22} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
          <div style={{ fontSize: 15, fontWeight: 600, color: PALETTE.espresso,
                        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {log.name}
          </div>
        </div>
        <div style={{ fontSize: 12, color: PALETTE.inkMuted, marginTop: 1,
                      display: 'flex', alignItems: 'center', gap: 6 }}>
          <span>{log.roaster}</span>
          <span style={{ width: 3, height: 3, borderRadius: 3, background: PALETTE.inkSoft }} />
          <span>{log.method}</span>
          <span style={{ width: 3, height: 3, borderRadius: 3, background: PALETTE.inkSoft }} />
          <span style={{ fontFeatureSettings: '"tnum"' }}>{log.date}</span>
        </div>
      </div>
      <ScoreRing score={log.score} />
    </div>
  );
}

const ACHIEVEMENTS = [
  { icon: '💯', title: '100 Cups',     sub: 'logged this season', color: '#F4E0C2' },
  { icon: '🏆', title: 'Brew Master',  sub: 'rated 90+ × 5',      color: '#E5D4BC' },
  { icon: '👃', title: 'Sensory Pro',  sub: 'all 8 flavors used',  color: '#DCC8AE' },
  { icon: '🔥', title: '14-day Streak',sub: 'keep it going',       color: '#F0D9BC' },
  { icon: '🌍', title: 'Origin Hunter',sub: '12 origins tasted',   color: '#D8C5A8', locked: true },
  { icon: '⏱',  title: 'Timer Hero',   sub: 'log 50 timers',       color: '#CDB89C', locked: true },
];

function Dashboard({ onNewLog, onOpenLog }) {
  const [logs, setLogs]         = React.useState([]);
  const [loading, setLoading]   = React.useState(true);
  const [loadError, setLoadError] = React.useState(false);
  const [minScoreIdx, setMinScoreIdx] = React.useState(0);

  const API_BASE = window.APP_API_BASE ?? '';

  React.useEffect(() => {
    let cancelled = false;
    fetch(`${API_BASE}/api/logs`)
      .then(r => {
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
      })
      .then(data => {
        if (cancelled) return;
        setLogs(Array.isArray(data) ? data : []);
        setLoading(false);
      })
      .catch(() => {
        if (cancelled) return;
        setLoadError(true);
        setLoading(false);
      });
    return () => { cancelled = true; };
  }, []);

  const now = new Date();
  const { weekCount, originsThisWeek, dayCounts, maxDay, avgScore, bestScore, avgTds } = React.useMemo(() => {
    // Week stats
    const weekStart = new Date(now); weekStart.setDate(now.getDate() - 6); weekStart.setHours(0,0,0,0);
    const weekLogs  = logs.filter(l => new Date(l.created_at) >= weekStart);

    // Bar chart — last 7 days
    const dayCounts = Array.from({ length: 7 }, (_, i) => {
      const d = new Date(now); d.setDate(now.getDate() - (6 - i)); const ds = d.toDateString();
      return logs.filter(l => new Date(l.created_at).toDateString() === ds).length;
    });

    // Aggregate stats
    const scores    = logs.map(deriveScore).filter(s => s > 0);
    const tdsVals   = logs.map(l => l.tds).filter(v => v != null);
    return {
      weekCount: weekLogs.length,
      originsThisWeek: new Set(weekLogs.map(l => l.roaster).filter(Boolean)).size,
      dayCounts,
      maxDay: Math.max(...dayCounts, 1),
      avgScore: scores.length ? (scores.reduce((a, b) => a + b, 0) / scores.length).toFixed(1) : '—',
      bestScore: scores.length ? Math.max(...scores) : '—',
      avgTds: tdsVals.length
        ? (tdsVals.reduce((a, b) => a + b, 0) / tdsVals.length).toFixed(2) + '%'
        : '—',
    };
  }, [logs]);

  const tg        = window.Telegram?.WebApp;
  const firstName = tg?.initDataUnsafe?.user?.first_name || 'there';

  const minScore = SCORE_STEPS[minScoreIdx];
  const displayLogs = React.useMemo(() => logs
    .filter(l => !minScore || deriveScore(l) >= minScore)
    .slice(0, 10)
    .map(mapLog), [logs, minScore]);

  return (
    <div style={{
      minHeight: '100%',
      background: `radial-gradient(140% 80% at 50% 0%, ${PALETTE.crema} 0%, ${PALETTE.cream} 50%, ${PALETTE.paper} 100%)`,
      paddingBottom: 40,
    }}>
      <div style={{ height: 60 }} />

      {/* top action bar */}
      <div style={{ display: 'flex', justifyContent: 'center', padding: '0 20px 16px' }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 6,
          padding: 6,
          background: 'rgba(36,23,18,0.92)',
          backdropFilter: 'blur(20px)',
          borderRadius: 999,
          boxShadow: '0 8px 24px rgba(36,23,18,0.28)',
        }}>
          <button style={{
            width: 44, height: 44, borderRadius: 999, border: 'none',
            background: 'transparent', color: PALETTE.crema,
            cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <CoffeeBean size={22} color={PALETTE.crema} tilt={-22} />
          </button>
          <button onClick={onNewLog} style={{
            height: 44, padding: '0 20px',
            borderRadius: 999, border: 'none',
            background: PALETTE.crema,
            color: PALETTE.espresso,
            fontSize: 14, fontWeight: 700, letterSpacing: 0.2,
            cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8,
            fontFamily: '-apple-system, system-ui',
          }}>
            <span style={{ display: 'inline-flex' }}>{Icon.plus(18)}</span>
            New tasting
          </button>
          <button style={{
            width: 44, height: 44, borderRadius: 999, border: 'none',
            background: 'transparent', color: PALETTE.crema,
            cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                 strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M3 12h18M3 6h18M3 18h12"/>
            </svg>
          </button>
        </div>
      </div>

      {/* greeting + avatar */}
      <div style={{ padding: '4px 20px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontSize: 12, color: PALETTE.inkMuted, letterSpacing: 0.4, fontWeight: 500 }}>
            {now.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })}
          </div>
          <div style={{ fontSize: 28, fontWeight: 700, color: PALETTE.espresso, letterSpacing: -0.6, lineHeight: 1.1, marginTop: 2 }}>
            {greeting()}, {firstName}<span style={{ color: PALETTE.caramel }}>.</span>
          </div>
        </div>
        <div style={{
          width: 40, height: 40, borderRadius: 20,
          background: `linear-gradient(135deg, ${PALETTE.caramel}, ${PALETTE.coffee})`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: PALETTE.crema, fontSize: 14, fontWeight: 700,
        }}>{firstName.slice(0, 2).toUpperCase()}</div>
      </div>

      {/* hero stats */}
      <div style={{ padding: '0 20px 16px' }}>
        <GlassCard padding={14} radius={24}>
          <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 10 }}>
            <div>
              <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: 1.2, textTransform: 'uppercase',
                            color: PALETTE.inkMuted }}>This week</div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 4 }}>
                <span style={{ fontSize: 36, fontWeight: 700, color: PALETTE.espresso, letterSpacing: -1, fontFeatureSettings: '"tnum"' }}>
                  {weekCount}
                </span>
                <span style={{ fontSize: 14, color: PALETTE.inkMuted, fontWeight: 500 }}>
                  {weekCount === 1 ? 'cup' : 'cups'}{originsThisWeek > 0 ? ` · ${originsThisWeek} origin${originsThisWeek > 1 ? 's' : ''}` : ''}
                </span>
              </div>
            </div>
          </div>

          {/* mini bar chart */}
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, height: 48,
                        padding: '4px 2px', borderTop: `0.5px solid ${PALETTE.hairline}` }}>
            {dayCounts.map((v, i) => (
              <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, paddingTop: 6 }}>
                <div style={{
                  width: '100%', height: `${Math.round((v / maxDay) * 36) + 4}px`,
                  background: i === 6 ? PALETTE.coffee : 'rgba(74,45,34,0.35)',
                  borderRadius: 4,
                }} />
                <div style={{ fontSize: 9, color: PALETTE.inkSoft, fontWeight: 600 }}>
                  {['S','M','T','W','T','F','S'][(new Date(now.getTime() - (6 - i) * 86400000)).getDay()]}
                </div>
              </div>
            ))}
          </div>

          <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
            <StatPill label="Avg score" value={avgScore} />
            <StatPill label="Best" value={bestScore} accent={PALETTE.sageDeep} />
            <StatPill label="TDS avg" value={avgTds} />
          </div>
        </GlassCard>
      </div>

      {/* achievements */}
      <SectionLabel kicker="6 unlocked · 14 total" style={{ padding: '8px 24px 8px' }}>
        Achievements
      </SectionLabel>
      <div style={{
        display: 'flex', gap: 10, padding: '0 20px 18px',
        overflowX: 'auto', scrollbarWidth: 'none',
      }}>
        {ACHIEVEMENTS.map((a, i) => <Achievement key={i} {...a} />)}
      </div>

      {/* logs */}
      <SectionLabel kicker={logs.length > 0 ? `${logs.length} total` : ''} style={{ padding: '4px 24px 8px' }}>
        Active logs
      </SectionLabel>
      <div style={{ display: 'flex', gap: 6, padding: '0 20px 10px', flexWrap: 'wrap' }}>
        {SCORE_STEPS.map((s, i) => (
          <button key={i} onClick={() => setMinScoreIdx(i)} style={{
            padding: '4px 10px', borderRadius: 999,
            fontSize: 12, fontWeight: 600, cursor: 'pointer',
            border: `0.5px solid ${i === minScoreIdx ? PALETTE.espresso : PALETTE.hairline}`,
            background: i === minScoreIdx ? PALETTE.espresso : 'rgba(255,252,246,0.7)',
            color: i === minScoreIdx ? PALETTE.crema : PALETTE.coffee,
            fontFamily: '-apple-system, system-ui',
          }}>{s === 0 ? 'All' : `${s}+`}</button>
        ))}
      </div>
      <div style={{ padding: '0 20px' }}>
        <GlassCard padding={2} radius={22}>
          {loading && (
            <div style={{ padding: 24, textAlign: 'center', color: PALETTE.inkMuted, fontSize: 13 }}>
              Loading…
            </div>
          )}
          {!loading && loadError && (
            <div style={{ padding: 24, textAlign: 'center', color: '#B71C1C', fontSize: 13 }}>
              Couldn't load logs — check the backend and refresh.
            </div>
          )}
          {!loading && !loadError && displayLogs.length === 0 && (
            <div style={{ padding: 24, textAlign: 'center', color: PALETTE.inkMuted, fontSize: 13 }}>
              No logs yet — tap New tasting to start.
            </div>
          )}
          {displayLogs.map((l, i) => (
            <React.Fragment key={l.id}>
              <LogRow log={l} onOpen={() => onOpenLog && onOpenLog(l)} />
              {i < displayLogs.length - 1 && (
                <div style={{ height: 0.5, background: PALETTE.hairline, marginLeft: 70 }} />
              )}
            </React.Fragment>
          ))}
        </GlassCard>
      </div>

    </div>
  );
}

Object.assign(window, { Dashboard });
