/* New creator — signing somebody to the book. The roster's create.
   Commit model: STAGED, its own route rather than a dialog: an audience is a
   row per platform and a rate card is a row per kind, which is a form, not a
   couple of fields (AGENTS §5).
   Data state: one — an empty form.
   Derivation while typing: reach and engagement are computed from the platform
   rows by the same helpers every other screen uses, and the open briefs this
   creator would fit are run through the real fit predicate against the real
   fixture. Nothing on this screen is a plausible number.
   Primary display: a form, single column, grouped as who / audience / what they
   cost. */
(() => {
  const {
    Button, Input, Textarea, Select, Checkbox, Card, CardHeader, CardTitle, CardDescription, CardPanel,
    Field, FieldLabel, FieldDescription, FieldError, Badge,
  } = window.OriginDesignSystem_7c998b;

  const BLANK = {
    name: "", handle: "", based: "", note: "", managerId: "", categories: [],
    platforms: [{ platform: "", followers: "", engagement: "" }],
    rates: {},
  };
  /* "3.8" means 3.8%, because that is how a rate is quoted in this trade. */
  const parseRate = (text) => {
    const cleaned = String(text).replace(/[^0-9.]/g, "");
    if (!cleaned) return NaN;
    return parseFloat(cleaned) / 100;
  };

  function NewCreatorScreen({ data, now, onNavigate, onCreate }) {
    const [draft, setDraft] = React.useState(BLANK);
    const [submitted, setSubmitted] = React.useState(false);
    const set = (fields) => { setSubmitted(false); setDraft(Object.assign({}, draft, fields)); };
    const dirty = JSON.stringify(draft) !== JSON.stringify(BLANK);

    const platforms = draft.platforms
      .filter((row) => row.platform && parseCount(row.followers) > 0 && !isNaN(parseRate(row.engagement)))
      .map((row) => ({ platform: row.platform, followers: parseCount(row.followers), engagementRate: parseRate(row.engagement) }));
    const rates = {};
    DELIVERABLE_KINDS.forEach((kind) => {
      const cents = parseMoney(draft.rates[kind.value] || "");
      if (!isNaN(cents) && cents > 0) rates[kind.value] = cents;
    });
    /* The draft as a creator, so the real helpers can read it. */
    const asCreator = {
      id: "draft", name: draft.name.trim() || "This creator", handle: draft.handle.trim(), based: draft.based.trim(),
      categories: draft.categories, status: "available", signedAt: now, note: draft.note.trim(),
      platforms: platforms, rates: rates, exclusivities: [], managerId: draft.managerId,
    };
    const reach = platforms.length ? reachOf(asCreator) : null;
    const engagement = platforms.length ? engagementOf(asCreator) : null;
    const card = platforms.length && Object.keys(rates).length ? rateCardOf(asCreator) : [];
    const fits = Object.keys(rates).length && platforms.length && draft.categories.length
      ? openBriefs(data.briefs).map((brief) => ({ brief: brief, fit: fitOf(asCreator, brief, now, data.deals) })).filter((row) => row.fit.fits)
      : [];
    const open = openBriefs(data.briefs);

    const errors = {};
    if (!draft.name.trim()) errors.name = "Their name, as it goes on a contract.";
    if (!draft.handle.trim()) errors.handle = "The handle brands will look them up by.";
    else if (data.creators.some((c) => c.handle.toLowerCase() === draft.handle.trim().replace(/^@/, "").toLowerCase())) errors.handle = "Somebody on the book already has that handle.";
    if (!draft.based.trim()) errors.based = "Where do they work from?";
    if (!draft.managerId) errors.managerId = "Somebody has to own them — an unowned creator is nobody's call to answer.";
    if (!draft.categories.length) errors.categories = "Pick at least one category, or no brief will ever match them.";
    if (!platforms.length) errors.platforms = "Add a platform with its followers and its engagement rate.";
    if (!Object.keys(rates).length) errors.rates = "A creator with no rate cannot be quoted for anything.";
    if (draft.note.trim().length < 20) errors.note = "Write the line you would say about them on a call — at least a sentence.";
    const valid = Object.keys(errors).length === 0;

    const setPlatform = (index, fields) => set({ platforms: draft.platforms.map((row, i) => (i === index ? Object.assign({}, row, fields) : row)) });
    const toggleCategory = (value) => set({ categories: draft.categories.indexOf(value) > -1 ? draft.categories.filter((c) => c !== value) : draft.categories.concat([value]) });

    const submit = () => {
      setSubmitted(true);
      if (!valid) return;
      onCreate({
        name: draft.name.trim(), handle: draft.handle.trim().replace(/^@/, ""), based: draft.based.trim(),
        note: draft.note.trim(), managerId: draft.managerId, categories: draft.categories,
        platforms: platforms, rates: rates,
      });
    };

    return (
      <div className="mq-page">
        <PageHead
          path="/talent/new"
          title="New creator"
          lede={"They join the book as free to pitch, with no exclusivity on file, and every open brief is matched against them from the moment you sign them. " + data.creators.length + " creators are on the book today."}
        />

        <Card>
          <CardHeader>
            <CardTitle>Who they are</CardTitle>
            <CardDescription>The categories are what a brief is matched on; the note is what you would say about them on a call.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel htmlFor="mq-nc-name">Name</FieldLabel>
                <Input id="mq-nc-name" value={draft.name} placeholder="Marisol Duarte" invalid={submitted && !!errors.name} onChange={(e) => set({ name: e.target.value })} />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nc-handle">Handle</FieldLabel>
                <Input id="mq-nc-handle" value={draft.handle} startAddon="@" placeholder="marisolduarte" invalid={submitted && !!errors.handle} onChange={(e) => set({ handle: e.target.value })} />
                {submitted && errors.handle ? <FieldError>{errors.handle}</FieldError> : <FieldDescription>One handle, however many platforms they are on.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nc-based">Based</FieldLabel>
                <Input id="mq-nc-based" value={draft.based} placeholder="Mexico City" invalid={submitted && !!errors.based} onChange={(e) => set({ based: e.target.value })} />
                {submitted && errors.based ? <FieldError>{errors.based}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nc-manager">Manager</FieldLabel>
                <Select
                  id="mq-nc-manager" value={draft.managerId} placeholder="Who owns them?"
                  items={data.managers.filter((m) => m.role === MARQUE_USER.role).map((m) => ({ value: m.id, label: m.name + " · " + creatorsForManager(data.creators, m).length + " on their book" }))}
                  onValueChange={(v) => set({ managerId: v })}
                />
                {submitted && errors.managerId ? <FieldError>{errors.managerId}</FieldError> : <FieldDescription>Ownership is a field on the creator, and the team screen reads it.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel>Categories</FieldLabel>
                <div className="mq-checks">
                  {CATEGORIES.map((category) => (
                    <label className="mq-check" key={category.value}>
                      <Checkbox checked={draft.categories.indexOf(category.value) > -1} onCheckedChange={() => toggleCategory(category.value)} />
                      <span className="mq-check__text">{category.label}</span>
                    </label>
                  ))}
                </div>
                {submitted && errors.categories ? <FieldError>{errors.categories}</FieldError> : <FieldDescription>{open.length} briefs are open right now, in {open.map((b) => labelOf(CATEGORIES, b.category).toLowerCase()).filter((c, i, all) => all.indexOf(c) === i).join(", ")}.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nc-note">The line about them</FieldLabel>
                <Textarea id="mq-nc-note" rows={2} value={draft.note} placeholder="Slow-build interiors with a joinery bent. Brands buy the hands, not the face." invalid={submitted && !!errors.note} onChange={(e) => set({ note: e.target.value })} />
                {submitted && errors.note ? <FieldError>{errors.note}</FieldError> : null}
              </Field>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Audience</CardTitle>
            <CardDescription>One row per platform. Reach and engagement are never stored — they are computed from these rows, so correcting a follower count later moves every figure that mentions it.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <div className="mq-repeat mq-repeat__head" aria-hidden="true"><span>Platform</span><span>Followers</span><span>Engagement</span><span /></div>
              {draft.platforms.map((row, index) => (
                <div className="mq-repeat" key={index}>
                  <Select size="sm" value={row.platform} placeholder="Platform" items={platformItems()} onValueChange={(v) => setPlatform(index, { platform: v })} />
                  <Input size="sm" inputMode="numeric" aria-label="Followers" placeholder="1400000" value={row.followers} onChange={(e) => setPlatform(index, { followers: e.target.value })} />
                  <Input size="sm" inputMode="decimal" aria-label="Engagement rate" endAddon="%" placeholder="1.9" value={row.engagement} onChange={(e) => setPlatform(index, { engagement: e.target.value })} />
                  {draft.platforms.length > 1 ? (
                    <Button variant="ghost" size="xs" aria-label="Remove this platform" onClick={() => set({ platforms: draft.platforms.filter((p, i) => i !== index) })}>Remove</Button>
                  ) : <span />}
                </div>
              ))}
              {submitted && errors.platforms ? <FieldError>{errors.platforms}</FieldError> : null}
              <div className="mq-stack">
                <Button variant="outline" size="sm" onClick={() => set({ platforms: draft.platforms.concat([{ platform: "", followers: "", engagement: "" }]) })}>Add a platform</Button>
                <span className="mq-note">
                  {reach === null
                    ? "Fill a row in and the totals appear."
                    : formatFollowers(reach) + " of audience at " + formatPercent(engagement) + " engaged, across " + platforms.length + " " + (platforms.length === 1 ? "platform" : "platforms") + " — " + labelOf(PLATFORMS, leadPlatformOf(asCreator).platform) + " carries " + formatPercent(leadPlatformOf(asCreator).followers / reach) + " of it."}
                </span>
              </div>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Rate card</CardTitle>
            <CardDescription>Organic, before usage. Leave a kind empty and it is work they do not take — a brief asking for it gets no quote from them rather than a quote that prices it at nothing.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              {DELIVERABLE_KINDS.map((kind) => (
                <Field key={kind.value}>
                  <FieldLabel htmlFor={"mq-nc-rate-" + kind.value}>{kind.label}</FieldLabel>
                  <Input
                    id={"mq-nc-rate-" + kind.value} inputMode="decimal" startAddon="$" placeholder="Not offered"
                    value={draft.rates[kind.value] || ""}
                    onChange={(e) => set({ rates: Object.assign({}, draft.rates, { [kind.value]: e.target.value }) })}
                  />
                </Field>
              ))}
              {submitted && errors.rates ? <FieldError>{errors.rates}</FieldError> : null}
              <div className="mq-col mq-col--tight">
                <span className="mq-note">
                  {card.length === 0
                    ? "Price at least one kind and the range appears here."
                    : card.length + " of " + DELIVERABLE_KINDS.length + " kinds priced, " + formatMoney(rateFloorOf(asCreator)) + " – " + formatMoney(rateCeilOf(asCreator)) + " a piece. Usage is charged on top: " + USAGE_SCOPES.filter((u) => u.uplift > 0).map((u) => u.label.toLowerCase() + " +" + Math.round(u.uplift * 100) + "%").join(", ") + "."}
                </span>
                {fits.length ? (
                  <div className="mq-stack">
                    <Badge size="sm" variant="success">Fits {fits.length} of {open.length} open {open.length === 1 ? "brief" : "briefs"}</Badge>
                    <span className="mq-note">{fits.map((row) => row.brief.brand + " at " + formatMoney(row.fit.quote.totalCents) + " against " + formatMoney(row.brief.budgetCents)).join(" · ")}</span>
                  </div>
                ) : (
                  <span className="mq-note">As entered, they fit none of the {open.length} open briefs on their category, audience and rate together.</span>
                )}
              </div>
            </div>
          </CardPanel>
        </Card>

        <FormBar
          dirty={dirty}
          note={dirty ? "Nobody has been signed yet." : "An empty file. Fill it in from their deck."}
          onCancel={() => { setDraft(BLANK); setSubmitted(false); }}
          onSave={submit}
          label="New creator"
        />
      </div>
    );
  }

  Object.assign(window, { NewCreatorScreen });
})();
