/* New brief — logging what a brand has sent in. The front door of the product:
   every brief on the desk arrived through here or through the fixture.
   Commit model: STAGED, and it is its own route rather than a dialog because
   the form is fifteen fields across five groups (AGENTS §5). Nothing applies
   until New brief; Cancel appears once dirty; errors render on submit.
   Data state: one — an empty form. There is no record yet to be loading or
   missing.
   Derivation while typing: the quote floor is read off the roster as the
   deliverable lines change, so the screen can say what the cheapest complete
   quote on the book would be against the budget being typed. It is the same
   rosterFloor() the match screen and the pass dialog run.
   Primary display: a form, single column, grouped by the question each group
   answers. */
(() => {
  const {
    Button, Input, Textarea, Select, Checkbox, Card, CardHeader, CardTitle, CardDescription, CardPanel,
    Field, FieldLabel, FieldDescription, FieldError, Separator,
  } = window.OriginDesignSystem_7c998b;

  const BLANK = {
    brandId: "", newBrandName: "", newBrandSector: "", newBrandHq: "",
    title: "", category: "", ask: "", budget: "", usage: "organic", audienceMin: "",
    lines: [{ kind: "", quantity: "1" }],
    liveFrom: "", liveTo: "", respondBy: "",
    contactName: "", contactRole: "",
  };
  const NEW_BRAND = "__new__";
  const dayOf = (value) => (value ? Date.parse(value + "T09:00:00Z") : null);

  function NewBriefScreen({ 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 lines = draft.lines
      .filter((line) => line.kind && parseCount(line.quantity) > 0)
      .map((line) => ({ kind: line.kind, quantity: parseCount(line.quantity) }));
    const budgetCents = parseMoney(draft.budget);
    /* A shape complete enough to price. The floor is derived from the roster, so
       signing a cheaper creator moves what this screen says. */
    const shape = lines.length && draft.usage ? { deliverables: lines, usage: draft.usage, category: draft.category, budgetCents: isNaN(budgetCents) ? 0 : budgetCents } : null;
    const floor = shape ? rosterFloor(data.creators, shape) : null;
    const cheapest = shape ? cheapestFitCreator(data.creators, shape) : null;

    const errors = {};
    if (!draft.brandId) errors.brandId = "Say who it came from.";
    if (draft.brandId === NEW_BRAND) {
      if (!draft.newBrandName.trim()) errors.newBrandName = "Name the brand.";
      if (!draft.newBrandSector) errors.newBrandSector = "Pick the sector they sell in.";
      if (!draft.newBrandHq.trim()) errors.newBrandHq = "Where are they based?";
    }
    if (!draft.title.trim()) errors.title = "Give the campaign the name they call it.";
    if (!draft.category) errors.category = "Pick the category — it is what the roster is matched on.";
    if (draft.ask.trim().length < 20) errors.ask = "Paste their ask, in their words — at least a sentence.";
    if (isNaN(budgetCents) || budgetCents <= 0) errors.budget = "Enter the budget for one creator.";
    if (!lines.length) errors.lines = "Add at least one deliverable with a quantity.";
    if (!dayOf(draft.liveFrom)) errors.liveFrom = "When do they want it live?";
    if (!dayOf(draft.liveTo)) errors.liveTo = "When does the window close?";
    else if (dayOf(draft.liveFrom) && dayOf(draft.liveTo) < dayOf(draft.liveFrom)) errors.liveTo = "The window closes before it opens.";
    if (!dayOf(draft.respondBy)) errors.respondBy = "When do they need an answer?";
    else if (dayOf(draft.respondBy) < now) errors.respondBy = "That date has passed.";
    if (!draft.contactName.trim()) errors.contactName = "Who sent it?";
    if (!draft.contactRole.trim()) errors.contactRole = "What is their title?";
    const valid = Object.keys(errors).length === 0;

    const submit = () => {
      setSubmitted(true);
      if (!valid) return;
      onCreate({
        brandId: draft.brandId,
        newBrand: draft.brandId === NEW_BRAND
          ? { name: draft.newBrandName.trim(), sector: draft.newBrandSector, hq: draft.newBrandHq.trim() }
          : null,
        title: draft.title.trim(), category: draft.category, ask: draft.ask.trim(),
        budgetCents: budgetCents, usage: draft.usage,
        audienceMin: isNaN(parseCount(draft.audienceMin)) ? 0 : parseCount(draft.audienceMin),
        deliverables: lines,
        liveFromAt: dayOf(draft.liveFrom), liveToAt: dayOf(draft.liveTo), respondByAt: dayOf(draft.respondBy),
        contact: { name: draft.contactName.trim(), role: draft.contactRole.trim() },
      });
    };

    const setLine = (index, fields) => set({ lines: draft.lines.map((line, i) => (i === index ? Object.assign({}, line, fields) : line)) });

    return (
      <div className="mq-page">
        <PageHead
          path="/briefs/new"
          title="New brief"
          lede={"It lands on your desk to triage, with " + AGENCY_POLICY.dueSoonDays + " days of clock showing against the date they need an answer. Nothing is pitched until you match it to the roster."}
        />

        <Card>
          <CardHeader>
            <CardTitle>Who it came from</CardTitle>
            <CardDescription>A brand we have worked with brings its own history — briefs, campaigns and how long it takes to pay.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel htmlFor="mq-nb-brand">Brand</FieldLabel>
                <Select
                  id="mq-nb-brand" value={draft.brandId} placeholder="Pick the brand"
                  items={data.brands.slice().sort((a, b) => a.name.localeCompare(b.name)).map((b) => ({ value: b.id, label: b.name + " · " + briefsForBrand(data.briefs, b).length + (briefsForBrand(data.briefs, b).length === 1 ? " brief" : " briefs") }))
                    .concat([{ value: NEW_BRAND, label: "A brand we have not worked with" }])}
                  onValueChange={(v) => set({ brandId: v })}
                />
                {submitted && errors.brandId ? <FieldError>{errors.brandId}</FieldError> : null}
              </Field>
              {draft.brandId === NEW_BRAND ? (
                <>
                  <Field>
                    <FieldLabel htmlFor="mq-nb-bname">Brand name</FieldLabel>
                    <Input id="mq-nb-bname" value={draft.newBrandName} invalid={submitted && !!errors.newBrandName} onChange={(e) => set({ newBrandName: e.target.value })} />
                    {submitted && errors.newBrandName ? <FieldError>{errors.newBrandName}</FieldError> : <FieldDescription>Written once here, and every screen that names them reads it.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="mq-nb-bsector">Sector</FieldLabel>
                    <Select id="mq-nb-bsector" value={draft.newBrandSector} placeholder="What do they sell?" items={CATEGORIES} onValueChange={(v) => set({ newBrandSector: v })} />
                    {submitted && errors.newBrandSector ? <FieldError>{errors.newBrandSector}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="mq-nb-bhq">City</FieldLabel>
                    <Input id="mq-nb-bhq" value={draft.newBrandHq} placeholder="Copenhagen" invalid={submitted && !!errors.newBrandHq} onChange={(e) => set({ newBrandHq: e.target.value })} />
                    {submitted && errors.newBrandHq ? <FieldError>{errors.newBrandHq}</FieldError> : null}
                  </Field>
                </>
              ) : null}
              <Field>
                <FieldLabel htmlFor="mq-nb-contact">Their contact</FieldLabel>
                <Input id="mq-nb-contact" value={draft.contactName} placeholder="Ilse Brandão" invalid={submitted && !!errors.contactName} onChange={(e) => set({ contactName: e.target.value })} />
                {submitted && errors.contactName ? <FieldError>{errors.contactName}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-role">Their title</FieldLabel>
                <Input id="mq-nb-role" value={draft.contactRole} placeholder="Head of brand" invalid={submitted && !!errors.contactRole} onChange={(e) => set({ contactRole: e.target.value })} />
                {submitted && errors.contactRole ? <FieldError>{errors.contactRole}</FieldError> : <FieldDescription>Who we chase when the brief goes quiet.</FieldDescription>}
              </Field>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>What they are asking for</CardTitle>
            <CardDescription>The category is what the roster is matched on, and the audience floor is what disqualifies a creator before anything else does.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel htmlFor="mq-nb-title">Campaign</FieldLabel>
                <Input id="mq-nb-title" value={draft.title} placeholder="Winter barrier repair" invalid={submitted && !!errors.title} onChange={(e) => set({ title: e.target.value })} />
                {submitted && errors.title ? <FieldError>{errors.title}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-cat">Category</FieldLabel>
                <Select id="mq-nb-cat" value={draft.category} placeholder="Pick the category" items={CATEGORIES} onValueChange={(v) => set({ category: v })} />
                {submitted && errors.category ? <FieldError>{errors.category}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-ask">The ask, in their words</FieldLabel>
                <Textarea id="mq-nb-ask" rows={3} value={draft.ask} placeholder="Quote the brief. The creator reads the brand, not your summary of it." invalid={submitted && !!errors.ask} onChange={(e) => set({ ask: e.target.value })} />
                {submitted && errors.ask ? <FieldError>{errors.ask}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-budget">Budget, per creator</FieldLabel>
                <Input id="mq-nb-budget" inputMode="decimal" startAddon="$" value={draft.budget} placeholder="225,000" invalid={submitted && !!errors.budget} onChange={(e) => set({ budget: e.target.value })} />
                {submitted && errors.budget ? <FieldError>{errors.budget}</FieldError> : <FieldDescription>What one creator's whole campaign is worth to them.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-audience">Audience floor</FieldLabel>
                <Input id="mq-nb-audience" inputMode="numeric" value={draft.audienceMin} placeholder="750000" onChange={(e) => set({ audienceMin: e.target.value })} />
                <FieldDescription>Leave it empty if they have not asked for one. {pitchableCreators(data.creators).length} of {data.creators.length} creators are free to pitch today.</FieldDescription>
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-usage">Usage rights</FieldLabel>
                <Select id="mq-nb-usage" value={draft.usage} items={USAGE_SCOPES.map((u) => ({ value: u.value, label: u.label + (u.uplift ? " · +" + Math.round(u.uplift * 100) + "% on the fee, " + u.months + " months" : " · no uplift") }))} onValueChange={(v) => set({ usage: v })} />
                <FieldDescription>The uplift is priced into every quote, and a time-limited window is tracked to the day it ends.</FieldDescription>
              </Field>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>What they want made</CardTitle>
            <CardDescription>A kind nobody on the book has a rate for is work we do not take, and the quote below says so rather than pricing it at nothing.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <div className="mq-repeat mq-repeat--pair mq-repeat__head" aria-hidden="true"><span>Deliverable</span><span>Quantity</span><span /></div>
              {draft.lines.map((line, index) => (
                <div className="mq-repeat mq-repeat--pair" key={index}>
                  <Select
                    size="sm" value={line.kind} placeholder="Pick a deliverable"
                    items={DELIVERABLE_KINDS} onValueChange={(v) => setLine(index, { kind: v })}
                  />
                  <Input size="sm" inputMode="numeric" aria-label="Quantity" value={line.quantity} onChange={(e) => setLine(index, { quantity: e.target.value })} />
                  {draft.lines.length > 1 ? (
                    <Button variant="ghost" size="xs" aria-label="Remove this line" onClick={() => set({ lines: draft.lines.filter((l, i) => i !== index) })}>Remove</Button>
                  ) : <span />}
                </div>
              ))}
              {submitted && errors.lines ? <FieldError>{errors.lines}</FieldError> : null}
              <div className="mq-stack">
                <Button variant="outline" size="sm" onClick={() => set({ lines: draft.lines.concat([{ kind: "", quantity: "1" }]) })}>Add a deliverable</Button>
                <span className="mq-note">
                  {!shape
                    ? "Add a line and the quote floor appears."
                    : floor === null
                      ? "Nobody on the book takes all of this, so there is no quote to compare against the budget."
                      : "The cheapest complete quote on the book is " + formatMoney(floor) + " — " + cheapest.creator.name + (isNaN(budgetCents) || budgetCents <= 0 ? "." : floor <= budgetCents ? ", inside the budget." : ", which is " + formatMoney(floor - budgetCents) + " over the budget.")}
                </span>
              </div>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Dates</CardTitle>
            <CardDescription>Availability is judged against the start of their window, never against today — a creator booked until October is free for a campaign starting in November.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel htmlFor="mq-nb-from">Live from</FieldLabel>
                <Input id="mq-nb-from" type="date" value={draft.liveFrom} invalid={submitted && !!errors.liveFrom} onChange={(e) => set({ liveFrom: e.target.value })} />
                {submitted && errors.liveFrom ? <FieldError>{errors.liveFrom}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-to">Live to</FieldLabel>
                <Input id="mq-nb-to" type="date" value={draft.liveTo} invalid={submitted && !!errors.liveTo} onChange={(e) => set({ liveTo: e.target.value })} />
                {submitted && errors.liveTo ? <FieldError>{errors.liveTo}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-nb-respond">They need an answer by</FieldLabel>
                <Input id="mq-nb-respond" type="date" value={draft.respondBy} invalid={submitted && !!errors.respondBy} onChange={(e) => set({ respondBy: e.target.value })} />
                {submitted && errors.respondBy ? <FieldError>{errors.respondBy}</FieldError> : <FieldDescription>This is the clock the triage deck counts down.</FieldDescription>}
              </Field>
            </div>
          </CardPanel>
        </Card>

        <FormBar
          dirty={dirty}
          note={dirty ? "Nothing has been logged yet." : "An empty brief. Fill it in as it arrived."}
          onCancel={() => { setDraft(BLANK); setSubmitted(false); }}
          onSave={submit}
          label="New brief"
        />
      </div>
    );
  }

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