import { useEffect, useState } from 'react';
import type { Activity } from '@backspace/shared';
import { getPrimaryActivity } from '@backspace/shared/src/activities.js';

interface ProfileActivityProps {
  activities: Activity[];
}

const VERB: Record<Activity['type'], string> = {
  playing: 'Playing',
  listening: 'Listening to',
  watching: 'Watching',
  streaming: 'Streaming',
  custom: '',
};

function formatClock(ms: number): string {
  const total = Math.max(0, Math.floor(ms / 1000));
  const minutes = Math.floor(total / 60);
  const seconds = total % 60;
  const hours = Math.floor(minutes / 60);
  if (hours > 0) return `${hours}:${String(minutes % 60).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
  return `${minutes}:${String(seconds).padStart(2, '0')}`;
}

/**
 * The activity block on the profile card — the "Listening to Spotify" panel.
 *
 * Deliberately richer than `ActivityCard` (which renders name + elapsed for
 * compact list rows): here there is room for the artwork, the track and the
 * artist, so it reads `details`, `state` and `assets` too. Every one of those
 * is optional and the block degrades to just the name, which is all today's
 * process-based detector supplies — the extra fields are what a Spotify
 * producer would fill in.
 */
export function ProfileActivity({ activities }: ProfileActivityProps) {
  const primary = getPrimaryActivity(activities);
  const start = primary?.timestamps?.start;
  const end = primary?.timestamps?.end;

  // Re-render once a second only while there is a clock to advance.
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    if (!start) return;
    const id = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(id);
  }, [start]);

  if (!primary || primary.type === 'custom') return null;

  const elapsed = start ? now - start : 0;
  const duration = start && end ? end - start : 0;
  const progress = duration > 0 ? Math.min(Math.max(elapsed / duration, 0), 1) : 0;

  // The server restricts asset images to http(s); this mirrors that so a
  // record stored before that check cannot inject another scheme.
  const art = primary.assets?.largeImage;
  const artSrc = art && (art.startsWith('https://') || art.startsWith('http://')) ? art : null;

  return (
    <div>
      <span className="text-[11px] uppercase tracking-wide font-semibold text-txt-tertiary">
        {VERB[primary.type]} {primary.name}
      </span>
      <div className="mt-2 flex gap-3 rounded-lg bg-surface-elevated/40 p-2.5">
        {artSrc && (
          <img
            src={artSrc}
            alt={primary.assets?.largeText ?? ''}
            className="w-[60px] h-[60px] rounded object-cover flex-shrink-0"
            referrerPolicy="no-referrer"
            loading="lazy"
          />
        )}
        <div className="min-w-0 flex-1">
          {primary.details && (
            <div className="text-[13px] font-semibold text-txt-primary truncate">
              {primary.details}
            </div>
          )}
          {primary.state && (
            <div className="text-[12px] text-txt-secondary truncate">{primary.state}</div>
          )}
          {duration > 0 ? (
            <div className="mt-2">
              <div className="h-[3px] rounded-full bg-interactive-muted overflow-hidden">
                <div
                  className="h-full bg-txt-primary rounded-full"
                  style={{ width: `${progress * 100}%` }}
                />
              </div>
              <div className="flex justify-between text-[10px] text-txt-tertiary mt-1 tabular-nums">
                <span>{formatClock(elapsed)}</span>
                <span>{formatClock(duration)}</span>
              </div>
            </div>
          ) : start ? (
            <div className="text-[11px] text-txt-tertiary mt-1 tabular-nums">
              {formatClock(elapsed)} elapsed
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}
