/* New claim — opening a file when a claim letter arrives.
   Commit model: STAGED. Every control is a form field, nothing exists until
   Save, Cancel appears once the form is dirty, and errors render on validation
   rather than on first paint.
   Data state: populated (a form is never empty-stated).

   The panel on the right is not decoration: it runs the real evaluators on the
   draft. `liabilityCap` gives the ceiling the bill of lading imposes from the
   package and weight figures alone — before anything is assessed — and
   `CLAIM_FLAGS.timeBarAt` gives the deadline from the delivery date. Both are
   the same functions every other screen reads, so what the form promises is
   what the file will say. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel,
    Field, FieldLabel, FieldDescription, FieldError, Input, Textarea, Select, Button, Badge,
  } = window.OriginDesignSystem_7c998b;

  const EMAIL = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
  const NEW_CLAIMANT = "__new";
  const MIN_INCIDENT = 20;
  const EMPTY = {
    claimantId: "", newName: "", newContact: "", newEmail: "",
    bl: "", container: "", vessel: "", voyage: "", pol: "", pod: "",
    commodity: "", packages: "", weightKg: "", deliveredOn: "", claimed: "", incident: "",
  };

  const toDate = (value) => {
    if (!value) return null;
    const ms = Date.parse(value + "T09:00:00");
    return isNaN(ms) ? null : ms;
  };
  const toInt = (value) => {
    const n = Number(String(value).replace(/[^0-9]/g, ""));
    return value !== "" && !isNaN(n) && n > 0 ? n : null;
  };

  function NewClaimScreen({ data, now, forClaimant, onNavigate, onCreate }) {
    const [draft, setDraft] = React.useState(Object.assign({}, EMPTY, forClaimant ? { claimantId: forClaimant } : null));
    const [submitted, setSubmitted] = React.useState(false);
    const set = (fields) => setDraft(Object.assign({}, draft, fields));
    const dirty = JSON.stringify(draft) !== JSON.stringify(Object.assign({}, EMPTY, forClaimant ? { claimantId: forClaimant } : null));

    const claimantItems = data.claimants
      .slice()
      .sort((a, b) => a.name.localeCompare(b.name))
      .map((p) => ({ value: p.id, label: p.name }))
      .concat([{ value: NEW_CLAIMANT, label: "A claimant we have not had before…" }]);
    const isNew = draft.claimantId === NEW_CLAIMANT;

    const packages = toInt(draft.packages);
    const weightKg = toInt(draft.weightKg);
    const deliveredAt = toDate(draft.deliveredOn);
    const claimedCents = parseMoney(draft.claimed || "");
    /* The real evaluator, on the draft. Both figures exist long before an
       assessment does, which is the whole reason to show them here. */
    const cap = packages && weightKg ? liabilityCap({ packages: packages, weightKg: weightKg }) : null;
    const timeBarAt = deliveredAt ? CLAIM_FLAGS.timeBarAt({ deliveredAt: deliveredAt }) : null;
    const daysLeft = timeBarAt ? Math.round((timeBarAt - now) / 864e5) : null;
    const capBinds = cap && !isNaN(claimedCents) && claimedCents > cap.cents;

    const errors = {};
    if (!draft.claimantId) errors.claimantId = "Pick the claimant, or open a record for a new one.";
    if (isNew && !draft.newName.trim()) errors.newName = "Enter the claimant's name as it appears on the bill of lading.";
    if (isNew && !draft.newContact.trim()) errors.newContact = "Enter who we write to.";
    if (isNew && !EMAIL.test(draft.newEmail)) errors.newEmail = "Enter a valid email address.";
    if (!draft.bl.trim()) errors.bl = "The bill of lading number identifies the contract of carriage.";
    if (!draft.container.trim()) errors.container = "Enter the container number.";
    if (!draft.vessel.trim()) errors.vessel = "Enter the vessel.";
    if (!draft.pol.trim()) errors.pol = "Enter the load port.";
    if (!draft.pod.trim()) errors.pod = "Enter the discharge port.";
    if (!draft.commodity.trim()) errors.commodity = "Enter what was in the container.";
    if (!packages) errors.packages = "Packages set half of the liability cap. Enter a whole number.";
    if (!weightKg) errors.weightKg = "Weight sets the other half of the cap. Enter kilos.";
    if (!deliveredAt) errors.deliveredOn = "Delivery starts the one-year time bar.";
    else if (deliveredAt > now) errors.deliveredOn = "A claim cannot be filed before the cargo is delivered.";
    if (isNaN(claimedCents) || claimedCents <= 0) errors.claimed = "Enter the figure the claimant is holding us to.";
    if (draft.incident.trim().length < MIN_INCIDENT) errors.incident = "Describe the loss in a sentence — it is the line every other screen shows.";
    const valid = Object.keys(errors).length === 0;

    const submit = () => {
      setSubmitted(true);
      if (!valid) return;
      onCreate({
        claimantId: isNew ? null : draft.claimantId,
        newClaimant: isNew ? { name: draft.newName.trim(), contact: draft.newContact.trim(), email: draft.newEmail.trim(), lane: draft.pol.trim() + " → " + draft.pod.trim() } : null,
        bl: draft.bl.trim(), container: draft.container.trim(), vessel: draft.vessel.trim(), voyage: draft.voyage.trim() || "—",
        pol: draft.pol.trim(), pod: draft.pod.trim(), commodity: draft.commodity.trim(),
        packages: packages, weightKg: weightKg, deliveredAt: deliveredAt,
        claimedCents: claimedCents, incident: draft.incident.trim(),
      });
    };

    return (
      <div className="cd-page">
        <PageHead
          path="/claims/new"
          title="New claim"
          lede="Open a file from the claim letter. Nothing is assessed here — the file starts waiting on documents, with the whole checklist requested."
        />

        <div className="cd-split">
          <div className="cd-col">
            <Card>
              <CardHeader>
                <CardTitle>Who is claiming</CardTitle>
                <CardDescription>The claimant's own record collects every claim they file, so the same name is never opened twice.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="cd-fields">
                  <Field>
                    <FieldLabel htmlFor="cd-n-claimant">Claimant</FieldLabel>
                    <Select id="cd-n-claimant" items={claimantItems} placeholder="Pick a claimant…" value={draft.claimantId} invalid={submitted && !!errors.claimantId} onValueChange={(v) => set({ claimantId: v })} />
                    {submitted && errors.claimantId ? <FieldError>{errors.claimantId}</FieldError> : <FieldDescription>{formatPlural(data.claimants.length, "claimant")} have shipped with us.</FieldDescription>}
                  </Field>
                  {isNew ? (
                    <div className="cd-grid2">
                      <Field>
                        <FieldLabel htmlFor="cd-n-name">Name on the bill of lading</FieldLabel>
                        <Input id="cd-n-name" value={draft.newName} invalid={submitted && !!errors.newName} onChange={(e) => set({ newName: e.target.value })} />
                        {submitted && errors.newName ? <FieldError>{errors.newName}</FieldError> : null}
                      </Field>
                      <Field>
                        <FieldLabel htmlFor="cd-n-contact">Who we write to</FieldLabel>
                        <Input id="cd-n-contact" value={draft.newContact} invalid={submitted && !!errors.newContact} onChange={(e) => set({ newContact: e.target.value })} />
                        {submitted && errors.newContact ? <FieldError>{errors.newContact}</FieldError> : null}
                      </Field>
                      <Field>
                        <FieldLabel htmlFor="cd-n-email">Their email</FieldLabel>
                        <Input id="cd-n-email" type="email" value={draft.newEmail} invalid={submitted && !!errors.newEmail} onChange={(e) => set({ newEmail: e.target.value })} />
                        {submitted && errors.newEmail ? <FieldError>{errors.newEmail}</FieldError> : <FieldDescription>Every document request and offer goes here.</FieldDescription>}
                      </Field>
                    </div>
                  ) : null}
                </div>
              </CardPanel>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>The shipment</CardTitle>
                <CardDescription>Packages and weight set the liability cap; the delivery date starts the time bar. Both are shown as you type them.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="cd-grid2">
                  <Field>
                    <FieldLabel htmlFor="cd-n-bl">Bill of lading</FieldLabel>
                    <Input id="cd-n-bl" placeholder="CRVN-2606-00000" value={draft.bl} invalid={submitted && !!errors.bl} onChange={(e) => set({ bl: e.target.value })} />
                    {submitted && errors.bl ? <FieldError>{errors.bl}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-container">Container</FieldLabel>
                    <Input id="cd-n-container" placeholder="MSKU 0000000" value={draft.container} invalid={submitted && !!errors.container} onChange={(e) => set({ container: e.target.value })} />
                    {submitted && errors.container ? <FieldError>{errors.container}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-vessel">Vessel</FieldLabel>
                    <Input id="cd-n-vessel" placeholder="Tanager Bay" value={draft.vessel} invalid={submitted && !!errors.vessel} onChange={(e) => set({ vessel: e.target.value })} />
                    {submitted && errors.vessel ? <FieldError>{errors.vessel}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-voyage">Voyage</FieldLabel>
                    <Input id="cd-n-voyage" placeholder="214E" value={draft.voyage} onChange={(e) => set({ voyage: e.target.value })} />
                    <FieldDescription>Optional — the vessel and dates find it if the letter omits it.</FieldDescription>
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-pol">Load port</FieldLabel>
                    <Input id="cd-n-pol" placeholder="Genoa" value={draft.pol} invalid={submitted && !!errors.pol} onChange={(e) => set({ pol: e.target.value })} />
                    {submitted && errors.pol ? <FieldError>{errors.pol}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-pod">Discharge port</FieldLabel>
                    <Input id="cd-n-pod" placeholder="Charleston" value={draft.pod} invalid={submitted && !!errors.pod} onChange={(e) => set({ pod: e.target.value })} />
                    {submitted && errors.pod ? <FieldError>{errors.pod}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-commodity">Commodity</FieldLabel>
                    <Input id="cd-n-commodity" placeholder="Glazed floor tile" value={draft.commodity} invalid={submitted && !!errors.commodity} onChange={(e) => set({ commodity: e.target.value })} />
                    {submitted && errors.commodity ? <FieldError>{errors.commodity}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-delivered">Delivered on</FieldLabel>
                    <Input id="cd-n-delivered" type="date" value={draft.deliveredOn} invalid={submitted && !!errors.deliveredOn} onChange={(e) => set({ deliveredOn: e.target.value })} />
                    {submitted && errors.deliveredOn ? <FieldError>{errors.deliveredOn}</FieldError> : <FieldDescription>The one-year time bar runs from this date.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-packages">Packages</FieldLabel>
                    <Input id="cd-n-packages" inputMode="numeric" placeholder="240" value={draft.packages} invalid={submitted && !!errors.packages} onChange={(e) => set({ packages: e.target.value })} />
                    {submitted && errors.packages ? <FieldError>{errors.packages}</FieldError> : null}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-weight">Weight</FieldLabel>
                    <Input id="cd-n-weight" inputMode="numeric" endAddon="kg" placeholder="18400" value={draft.weightKg} invalid={submitted && !!errors.weightKg} onChange={(e) => set({ weightKg: e.target.value })} />
                    {submitted && errors.weightKg ? <FieldError>{errors.weightKg}</FieldError> : null}
                  </Field>
                </div>
              </CardPanel>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>The loss</CardTitle>
                <CardDescription>What they are holding us to, and what they say happened.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="cd-fields">
                  <Field>
                    <FieldLabel htmlFor="cd-n-claimed">Amount claimed</FieldLabel>
                    <div style={{ maxWidth: "14rem" }}>
                      <Input id="cd-n-claimed" inputMode="decimal" startAddon="$" placeholder="41,250.00" value={draft.claimed} invalid={submitted && !!errors.claimed} onChange={(e) => set({ claimed: e.target.value })} />
                    </div>
                    {submitted && errors.claimed ? <FieldError>{errors.claimed}</FieldError> : <FieldDescription>Their figure, before any deduction. Nothing is assessed until the evidence is in.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="cd-n-incident">What happened</FieldLabel>
                    <Textarea id="cd-n-incident" rows={4} placeholder="Lashing failure in hold 3 — six pallets crushed against the bulkhead" value={draft.incident} invalid={submitted && !!errors.incident} onChange={(e) => set({ incident: e.target.value })} />
                    {submitted && errors.incident ? <FieldError>{errors.incident}</FieldError> : <FieldDescription>One line, in the claimant's terms. It is the line the queue and every record header show.</FieldDescription>}
                  </Field>
                </div>
              </CardPanel>
            </Card>
          </div>

          <div className="cd-col">
            <Card>
              <CardHeader>
                <CardTitle>What the file will say</CardTitle>
                <CardDescription>Computed from the figures above by the same helpers every other screen uses.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="cd-col cd-col--tight">
                  <div>
                    <div className="cd-figure__label">Time bar</div>
                    {timeBarAt ? (
                      <>
                        <div className={"cd-figure " + clockClass(timeTone(daysLeft))} style={{ fontSize: "var(--text-2xl)" }}>{formatCountdown(timeBarAt, now)}</div>
                        <div style={{ marginBlock: "var(--space-2)" }}>
                          <TimeBar startAt={deliveredAt} endAt={timeBarAt} now={now} label={"Time bar: " + formatCountdown(timeBarAt, now)} />
                        </div>
                        <div className="cd-figure__note">Expires {formatAbsolute(timeBarAt).split(",")[0]}, {CLAIM_POLICY.timeBarDays} days after delivery.</div>
                      </>
                    ) : (
                      <div className="cd-figure__note">Set the delivery date to see the deadline.</div>
                    )}
                  </div>

                  <div>
                    <div className="cd-figure__label">Liability cap</div>
                    {cap ? (
                      <>
                        <div className="cd-figure" style={{ fontSize: "var(--text-2xl)" }}>{formatMoney(cap.cents)}</div>
                        <div className="cd-figure__note">
                          The higher of {formatCount(Math.round(cap.byPackageSdr))} SDR by package and {formatCount(Math.round(cap.byWeightSdr))} SDR by weight — the {cap.basis} basis binds, at {CLAIM_POLICY.sdrUsdRate} USD per SDR.
                        </div>
                      </>
                    ) : (
                      <div className="cd-figure__note">Enter packages and weight to see the ceiling the bill of lading imposes.</div>
                    )}
                  </div>

                  {capBinds ? (
                    <p className="cd-note">
                      The claim of {formatMoney(claimedCents)} is above that ceiling. Nothing is wrong with opening it — the cap simply binds at {formatMoney(cap.cents)} when it is assessed.
                    </p>
                  ) : null}

                  <div>
                    <div className="cd-figure__label">Evidence the file will request</div>
                    <div className="cd-rows" style={{ marginTop: "var(--space-2)" }}>
                      {DOCUMENT_TYPES.map((type) => (
                        <div className="cd-row" key={type.value} style={{ paddingBlock: "var(--space-2)" }}>
                          <div className="cd-row__main"><span style={{ fontSize: "var(--text-sm)" }}>{type.label}</span></div>
                          <div className="cd-row__side">{type.mandatory ? <Badge size="sm" variant="outline">Mandatory</Badge> : <span className="cd-record__meta">Optional</span>}</div>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </CardPanel>
            </Card>
          </div>
        </div>

        <div className="cd-formbar">
          <span className="cd-formbar__note">
            {submitted && !valid
              ? formatPlural(Object.keys(errors).length, "field") + " still to fill in."
              : "The file opens waiting on documents, with all " + formatCount(DOCUMENT_TYPES.length) + " requested from the claimant."}
          </span>
          {dirty ? <Button variant="outline" onClick={() => onNavigate("/")}>Cancel</Button> : null}
          <Button disabled={!dirty} onClick={submit}>Save claim</Button>
        </div>
      </div>
    );
  }

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