/* === Onboarding screen ===
   First screen a brand-new user lands on. A checklist of small setup
   steps that takes a homebook from "empty shell" to "actually useful in
   a few clicks." Each card auto-detects completion from existing state
   (no extra persistence) and routes to the relevant screen on tap.

   Required steps must be completed by adding real data:
     income · fixed · tags · goals
   Optional steps support a "Do later" skip:
     family (for solo users) · meals · tasks

   The screen stays accessible from the sidebar as long as any step is
   still unaddressed (incomplete AND not skipped). Once everything is
   either complete or skipped, the sidebar pin retires.

   See also: TODO.md for the broader onboarding design decisions and
   the planned dashboard banner that links here on first login. */

const ONBOARDING_STEPS = [
  {
    id: 'family',
    label: 'Family',
    copy: 'Add your partner or another adult sharing the household. Skip if you\'re using homebook solo.',
    route: 'family',
    optional: true,
  },
  {
    id: 'income',
    label: 'Income',
    copy: 'What\'s coming in each month — salaries, side gigs, anything regular. Sets the foundation for everything else.',
    route: 'baseline',
    optional: false,
  },
  {
    id: 'fixed',
    label: 'Fixed costs',
    copy: 'Recurring bills that come out of every paycheck — rent, utilities, subscriptions. Money already committed.',
    route: 'baseline',
    optional: false,
  },
  {
    id: 'tags',
    label: 'Tags',
    copy: 'Set monthly budgets on the categories your variable spending falls into. Drives the "On track / Over" pace tag.',
    route: 'expenses',
    optional: false,
  },
  {
    id: 'goals',
    label: 'Savings goals',
    copy: 'What you\'re working toward — a trip, an emergency fund, a down payment. Skip if you\'re not building toward anything specific yet.',
    route: 'goals',
    optional: true,
  },
  {
    id: 'meals',
    label: 'Meals',
    copy: 'Plan recipes and a weekly meal schedule. Pantry + shopping list flow from there.',
    route: 'meals',
    optional: true,
  },
  {
    id: 'tasks',
    label: 'Chores',
    copy: 'Shared household chores — due dates, priorities, who owns what.',
    route: 'tasks',
    optional: true,
  },
];

// Boolean predicates for "this step has been satisfied by real data."
// Kept centralized so the sidebar pin and the screen agree on the count.
function isStepComplete(state, id) {
  const s = state || {};
  switch (id) {
    case 'family': {
      // Only counts as complete when an additional adult is in the
      // household — "rename yourself" doesn't apply since invited
      // signups arrive pre-named via accept_invite(). Solo users
      // address this card via "Do later" instead.
      return (s.family || []).length > 1;
    }
    case 'income': return (s.incomeSources || []).length >= 1;
    case 'fixed':  return (s.fixed || []).length >= 1;
    case 'tags':   return (s.tags || []).some(t => (t.budget || 0) > 0);
    case 'goals':  return (s.goals || []).length >= 1;
    case 'meals':  return (s.recipes || []).length >= 1;
    case 'tasks':  return (s.tasks || []).length >= 1;
    default:       return false;
  }
}
function isStepSkipped(state, id) {
  return (state?.onboardingSkipped || []).includes(id);
}
function isStepAddressed(state, id) {
  return isStepComplete(state, id) || isStepSkipped(state, id);
}
// Used by the App shell to decide whether to land a brand-new user on
// the onboarding screen instead of the dashboard. We treat "no required
// step has been touched AND nothing's been skipped" as the new-user
// signal — once they've engaged with anything, we send them to the
// dashboard like a returning user.
function isFreshHousehold(state) {
  if (!state) return false;
  const requiredAny = ONBOARDING_STEPS.some(s => !s.optional && isStepComplete(state, s.id));
  const skippedAny  = (state.onboardingSkipped || []).length > 0;
  // Only fresh if NOTHING has been touched yet.
  return !requiredAny && !skippedAny;
}
// Used by the sidebar — pin "Get started" while there's at least one
// unaddressed step (incomplete AND not skipped).
function hasUnaddressedSteps(state) {
  if (!state) return false;
  return ONBOARDING_STEPS.some(s => !isStepAddressed(state, s.id));
}
// Sidebar pin visibility. Single rule: show whenever any step is
// unaddressed (incomplete AND not skipped). Earlier versions tried to
// be clever about distinguishing "established users" from "fresh"
// based on which required steps were complete, but that didn't survive
// edge cases — old-default tag budgets, the legacy income migration,
// or any other state quirk could silently mark a required step as
// complete and hide the pin from a user who clearly hadn't engaged.
// Now: if anything's unaddressed, show the pin. Established users who
// don't want to use Meals or Tasks click "Do later" once and the pin
// retires for good. One-time interaction beats a clever heuristic.
function shouldShowOnboardingPin(state) {
  if (!state) return false;
  return hasUnaddressedSteps(state);
}

function OnboardingScreen({ state, setState, setRoute }) {
  const total = ONBOARDING_STEPS.length;
  const addressed = ONBOARDING_STEPS.filter(s => isStepAddressed(state, s.id)).length;
  const allDone = addressed === total;

  // First time the user sees this screen, mark it. The sidebar's Get-
  // started pin keys off this flag so it shows for new users (who
  // landed here automatically) but stays hidden for existing
  // households (who never visit this screen and have no reason to see
  // a "set up" prompt for things they already know about).
  React.useEffect(() => {
    if (!state.onboardingShown) {
      setState(s => ({ ...s, onboardingShown: true }));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const skip = (id) => setState(s => ({
    ...s,
    onboardingSkipped: Array.from(new Set([...(s.onboardingSkipped || []), id])),
  }));
  const unskip = (id) => setState(s => ({
    ...s,
    onboardingSkipped: (s.onboardingSkipped || []).filter(x => x !== id),
  }));

  return (
    <>
      <div className="page-head">
        <div>
          <div className="page-sub">{addressed} of {total} addressed</div>
          <h1 className="page-title">Welcome to homebook</h1>
        </div>
      </div>

      <div className="onboarding-body">
        <p className="onboarding-intro">
          A few small steps to fill in your homebook. Take them in any order — your dashboard will fill in as you go. You can come back here anytime from the sidebar.
        </p>

        {allDone && (
          <div className="onboarding-complete">
            <span className="onboarding-complete-icon">✓</span>
            <div>
              <div className="onboarding-complete-title">You're all set up.</div>
              <div className="onboarding-complete-sub muted">Welcome to your homebook. Open the dashboard whenever you're ready.</div>
            </div>
          </div>
        )}

        <div className="onboarding-grid">
          {ONBOARDING_STEPS.map((step, idx) => {
            const complete = isStepComplete(state, step.id);
            const skipped  = !complete && isStepSkipped(state, step.id);
            return (
              <div key={step.id}
                   className={`onboarding-card ${complete ? 'complete' : ''} ${skipped ? 'skipped' : ''}`}>
                <div className="onboarding-card-head">
                  <span className="onboarding-card-num">{String(idx + 1).padStart(2, '0')}</span>
                  <span className="onboarding-card-label">{step.label}</span>
                  {complete && <span className="onboarding-card-status complete">✓ Done</span>}
                  {skipped  && <span className="onboarding-card-status skipped">Skipped</span>}
                </div>
                <p className="onboarding-card-copy">{step.copy}</p>
                <div className="onboarding-card-actions">
                  <button className="btn primary onboarding-card-cta"
                          onClick={() => setRoute && setRoute(step.route)}>
                    {complete ? 'Open' : skipped ? 'Set up now' : '+ Get started'}
                  </button>
                  {step.optional && !complete && !skipped && (
                    <button className="btn ghost" onClick={() => skip(step.id)}>
                      Do later
                    </button>
                  )}
                  {skipped && (
                    <button className="btn ghost" onClick={() => unskip(step.id)}>
                      Bring back
                    </button>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
}

Object.assign(window, {
  OnboardingScreen,
  ONBOARDING_STEPS,
  isStepComplete, isStepSkipped, isStepAddressed,
  isFreshHousehold, hasUnaddressedSteps, shouldShowOnboardingPin,
});
