/* global React, t, useCurrentVote, SHASTE_API */

function normalizeVoteData(source) {
  if (!source || typeof source !== 'object') return null;
  const vote = source.vote || source.currentVote || source.poll || source.data || source;
  if (!vote || typeof vote !== 'object') return null;

  const options = Array.isArray(vote.options)
    ? vote.options
    : (Array.isArray(vote.choices) ? vote.choices : []);

  return {
    id: vote.id || source.id || 'vote',
    title: vote.title || source.title || 'Which feature should we prioritize next?',
    description: vote.description || source.description || 'Vote now. Results unlock after you cast your vote.',
    options,
    selectedOptionId:
      vote.selectedOptionId
      || vote.selected_option_id
      || vote.userChoice
      || vote.user_choice
      || (vote.userVote && (vote.userVote.optionId || vote.userVote.option_id))
      || source.selectedOptionId
      || source.selected_option_id
      || null,
    resultsVisible: Boolean(
      vote.resultsVisible
      || vote.results_visible
      || vote.hasVoted
      || vote.has_voted
      || (vote.userVote && (vote.userVote.optionId || vote.userVote.option_id))
      || source.hasVoted
    ),
  };
}

function RoadmapPage({ setPage }) {
  const [roadmap, setRoadmap] = React.useState(null);
  const [roadmapError, setRoadmapError] = React.useState(null);
  const [activeMonth, setActiveMonth] = React.useState(0);
  const [submittingVoteId, setSubmittingVoteId] = React.useState(null);
  const [submitError, setSubmitError] = React.useState(null);
  const [localVote, setLocalVote] = React.useState(null);
  const { loading: voteLoading, error: voteError, data: voteData } = useCurrentVote();

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch('/content/roadmap.json');
        if (!res.ok) throw new Error(`Roadmap request failed (${res.status})`);
        const payload = await res.json();
        if (!cancelled) {
          setRoadmap(payload);
          const months = Array.isArray(payload?.global?.months) ? payload.global.months : [];
          const currentMonthIndex = months.findIndex((m) => m && m.current);
          setActiveMonth(currentMonthIndex >= 0 ? currentMonthIndex : 0);
        }
      } catch (err) {
        if (!cancelled) setRoadmapError(err);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  const months = React.useMemo(() => {
    return Array.isArray(roadmap?.global?.months) ? roadmap.global.months : [];
  }, [roadmap]);

  const games = React.useMemo(() => {
    return Array.isArray(roadmap?.games) ? roadmap.games : [];
  }, [roadmap]);

  const vote = React.useMemo(() => {
    return normalizeVoteData(localVote || voteData);
  }, [localVote, voteData]);

  const voteSelection = vote?.selectedOptionId || null;

  const submitVote = async (optionId) => {
    if (!optionId || submittingVoteId) return;
    setSubmittingVoteId(optionId);
    setSubmitError(null);
    try {
      const response = await SHASTE_API.submitVote(optionId);
      const normalizedResponse = normalizeVoteData(response);
      if (normalizedResponse) {
        setLocalVote(normalizedResponse);
      } else {
        setLocalVote({
          ...vote,
          selectedOptionId: optionId,
          resultsVisible: true,
        });
      }
    } catch (err) {
      setSubmitError(err);
    } finally {
      setSubmittingVoteId(null);
    }
  };

  return (
    <div className="container fade-in">
      <div style={{ marginTop: 12 }}>
        <div className="eyebrow">{t('roadmap.eyebrow')}</div>
        <h1 className="h-display" style={{ fontSize: 'clamp(36px, 4.5vw, 52px)', marginTop: 6 }}>{t('roadmap.title')}</h1>
        <p style={{ color: 'var(--muted)', marginTop: 10, maxWidth: 640 }}>
          {roadmap?.global?.intro || t('roadmap.desc')}
        </p>
      </div>

      {roadmapError && (
        <div className="card" style={{ marginTop: 18, color: 'var(--danger)' }}>
          Failed to load roadmap data.
        </div>
      )}

      {!!months.length && (
        <section style={{ marginTop: 24 }}>
          <div className="eyebrow" style={{ marginBottom: 8 }}>{roadmap?.global?.heading || 'Global calendar'}</div>
          <div style={{ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap' }}>
            {months.map((month, index) => (
              <button
                key={`${month?.label || 'month'}-${index}`}
                type="button"
                onClick={() => setActiveMonth(index)}
                className={`btn ${index === activeMonth ? '' : 'btn--ghost'}`}
                style={{ padding: '8px 12px' }}
              >
                {month?.label || `Month ${index + 1}`}
              </button>
            ))}
          </div>
          <div className="card" style={{ padding: 12 }}>
            <img
              src={months[activeMonth]?.image}
              alt={months[activeMonth]?.label || 'Roadmap month'}
              style={{ width: '100%', borderRadius: 12, display: 'block' }}
            />
          </div>
        </section>
      )}

      <section style={{ marginTop: 24, display: 'grid', gap: 12 }}>
        {games.map((game) => (
          <article key={game.slug || game.title} className="card" style={{ padding: 16 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
              <div>
                <div className="eyebrow" style={{ fontSize: 11 }}>{(game.universe || '').toUpperCase()}</div>
                <h3 style={{ margin: '6px 0 0', fontSize: 18 }}>{game.title}</h3>
              </div>
              <span className="pill pill--follower">{game.status || t('roadmap.in_progress')}</span>
            </div>
            <p style={{ color: 'var(--subtle)', marginTop: 8 }}>{game.pitch}</p>
            <div style={{ marginTop: 8, color: 'var(--subtle)', fontSize: 13 }}>
              <strong style={{ color: 'var(--text)' }}>Version:</strong> {game.current_version || '—'} → {game.next_version || '—'}
            </div>
            <ul style={{ margin: '10px 0 0', paddingLeft: 18, display: 'grid', gap: 4 }}>
              {(Array.isArray(game.next_focus) ? game.next_focus : []).map((item, idx) => (
                <li key={`${game.slug || game.title}-focus-${idx}`}>{item}</li>
              ))}
            </ul>
            {game.link && (
              <a href={game.link} className="btn btn--ghost" style={{ marginTop: 12, display: 'inline-flex' }}>
                Open game
              </a>
            )}
          </article>
        ))}
      </section>

      <section className="card" style={{ marginTop: 24, padding: 16 }}>
        <div className="eyebrow" style={{ marginBottom: 6 }}>Community vote</div>
        {voteLoading && !vote && <p style={{ color: 'var(--subtle)' }}>Loading vote…</p>}
        {!voteLoading && !vote && <p style={{ color: 'var(--subtle)' }}>No active vote right now.</p>}
        {vote && (
          <>
            <h3 style={{ margin: 0, fontSize: 20 }}>{vote.title}</h3>
            <p style={{ color: 'var(--subtle)', marginTop: 6 }}>{vote.description}</p>
            <div style={{ marginTop: 12, display: 'grid', gap: 8 }}>
              {vote.options.map((option, index) => {
                const optionId = option?.id || option?.optionId || `option-${index}`;
                const isSelected = voteSelection === optionId;
                const votesCount = Number.isFinite(Number(option?.votes)) ? Number(option.votes) : null;
                const percentValue = Number.isFinite(Number(option?.percent)) ? Number(option.percent) : null;
                return (
                  <button
                    key={optionId}
                    type="button"
                    className={`btn ${isSelected ? '' : 'btn--ghost'}`}
                    onClick={() => submitVote(optionId)}
                    disabled={!!voteSelection || !!submittingVoteId}
                    style={{ justifyContent: 'space-between', textAlign: 'left', width: '100%', gap: 10 }}
                  >
                    <span>{option?.label || option?.title || `Option ${index + 1}`}</span>
                    {(vote.resultsVisible && (votesCount !== null || percentValue !== null)) && (
                      <span style={{ color: 'var(--subtle)', fontSize: 12 }}>
                        {percentValue !== null ? `${percentValue}%` : ''}{percentValue !== null && votesCount !== null ? ' • ' : ''}{votesCount !== null ? `${votesCount} votes` : ''}
                      </span>
                    )}
                  </button>
                );
              })}
            </div>
          </>
        )}
        {(voteError || submitError) && (
          <p style={{ color: 'var(--danger)', marginTop: 10 }}>
            {submitError ? 'Vote failed. Please try again.' : 'Could not load vote.'}
          </p>
        )}
      </section>

      <button onClick={() => setPage('home')} className="btn btn--ghost" style={{ marginTop: 22 }}>{t('action.back_to_hub')}</button>
    </div>
  );
}

Object.assign(window, { RoadmapPage });
