"use client";

import { VehicleType, VehicleTypeCounts, ZoneParkingInput } from "@/lib/api";
import { useLocale } from "@/i18n/LocaleProvider";
import { useVehicleTypes } from "@/lib/useVehicleTypes";
import { Field, SegmentedControl, Toggle } from "@/components/ui";


/**
 * The parking-only half of the zone form, shared by the create form and the edit panel so the
 * two can never drift apart on validation or wording.
 *
 * <p>Capacity is one row per vehicle type rather than a repeatable "add another" list. A
 * repeatable list lets an operator enter the same type twice with different numbers, and then
 * nothing can say which one is real; a fixed row per type makes that unrepresentable. A blank
 * row means "this spot does not take this kind", which is why blank is not the same as zero.
 */
export function ParkingFields({
  value,
  onChange,
}: {
  value: ZoneParkingInput;
  onChange: (next: ZoneParkingInput) => void;
}) {
  const { t } = useLocale();
  // Capacity is declared per vehicle type, so the rows follow the catalogue rather than a fixed
  // three: a spot for cargo bikes needs a cargo-bike row.
  const { active: activeTypes, label: typeLabel } = useVehicleTypes();
  const set = (patch: Partial<ZoneParkingInput>) => onChange({ ...value, ...patch });

  const setCapacity = (type: VehicleType, raw: string) => {
    const next: VehicleTypeCounts = { ...(value.capacity ?? {}) };
    const n = Number(raw);
    if (raw.trim() === "" || !Number.isFinite(n) || n <= 0) {
      delete next[type];
    } else {
      next[type] = Math.floor(n);
    }
    set({ capacity: next });
  };

  const open24x7 = value.open24x7 ?? true;
  // Free or paid is read back out of the one number, so nothing can disagree with it:
  //   0 (or absent) -> free
  //   null          -> paid, amount not entered yet
  //   > 0           -> paid
  // The null state exists so picking "Paid" does not immediately read back as free and snap the
  // choice away, and so a half-finished spot cannot be saved as free by accident.
  const paid = value.parkingFee === null || (value.parkingFee ?? 0) > 0;

  return (
    <div className="space-y-4 rounded-card border border-line p-4">
      <p className="text-sm font-medium">{t("zones.parkingSection")}</p>

      {/* The ops name above is for staff; these are what a rider reads on the map pin. */}
      <div className="grid gap-4 sm:grid-cols-2">
        <Field
          label={t("zones.riderNameEn")}
          value={value.riderNameEn ?? ""}
          onChange={(e) => set({ riderNameEn: e.target.value })}
          placeholder="Olaya Station"
          dir="ltr"
          maxLength={64}
        />
        <Field
          label={t("zones.riderNameAr")}
          value={value.riderNameAr ?? ""}
          onChange={(e) => set({ riderNameAr: e.target.value })}
          placeholder="محطة العليا"
          dir="rtl"
          maxLength={64}
        />
      </div>
      <p className="text-xs text-muted">{t("zones.riderNameHint")}</p>

      {/* Free or paid is one number underneath: fee 0 IS free, so the two can never disagree.
          The choice is presented as a pair of buttons because "type 0" is not how an operator
          thinks about a free spot. */}
      <div>
        <label className="field-label">{t("zones.price")}</label>
        <div className="mt-1">
          <SegmentedControl
            value={paid ? "PAID" : "FREE"}
            onChange={(next) =>
              // Switching to free zeroes the amount rather than remembering it, so a spot cannot
              // display "Free" while still carrying a fee it would charge if toggled back.
              set({ parkingFee: next === "FREE" ? 0 : value.parkingFee || null })
            }
            options={[
              { value: "FREE", label: t("zones.free") },
              { value: "PAID", label: t("zones.paid") },
            ]}
          />
        </div>
        {paid && (
          <div className="mt-3">
            <Field
              label={t("zones.fee")}
              value={value.parkingFee == null ? "" : String(value.parkingFee)}
              onChange={(e) => {
                const n = Number(e.target.value);
                set({ parkingFee: e.target.value.trim() === "" || !Number.isFinite(n) ? null : n });
              }}
              inputMode="decimal"
              dir="ltr"
              placeholder="2.50"
            />
            <p className="mt-1 text-xs text-muted">{t("zones.feeHint")}</p>
          </div>
        )}
      </div>

      <div>
        <label className="field-label">{t("zones.capacity")}</label>
        <div className="mt-1 grid gap-3 sm:grid-cols-3">
          {activeTypes.map(({ code: type }) => (
            <Field
              key={type}
              label={typeLabel(type)}
              value={String(value.capacity?.[type] ?? "")}
              onChange={(e) => setCapacity(type, e.target.value)}
              placeholder="-"
              inputMode="numeric"
              dir="ltr"
            />
          ))}
        </div>
        <p className="mt-2 text-xs text-muted">{t("zones.capacityHint")}</p>
      </div>

      <div className="flex items-center justify-between">
        <span className="text-sm">{t("zones.open24x7")}</span>
        <Toggle
          checked={open24x7}
          onChange={(v) =>
            // Clearing the hours alongside the toggle keeps the payload honest: the server drops
            // them anyway, and leaving them on screen suggests they still apply.
            set(v ? { open24x7: true, opensAt: null, closesAt: null } : { open24x7: false })
          }
          label={t("zones.open24x7")}
        />
      </div>

      {!open24x7 && (
        <div className="grid gap-4 sm:grid-cols-2">
          <Field
            label={t("zones.opensAt")}
            type="time"
            value={value.opensAt ?? ""}
            onChange={(e) => set({ opensAt: e.target.value })}
            dir="ltr"
          />
          <Field
            label={t("zones.closesAt")}
            type="time"
            value={value.closesAt ?? ""}
            onChange={(e) => set({ closesAt: e.target.value })}
            dir="ltr"
          />
          {/* Overnight windows are supported and common for a spot that shuts at night, so the
              hint says so rather than letting someone assume the times must be in order. */}
          <p className="text-xs text-muted sm:col-span-2">{t("zones.hoursHint")}</p>
        </div>
      )}

      <Field
        label={t("zones.note")}
        value={value.note ?? ""}
        onChange={(e) => set({ note: e.target.value })}
        placeholder={t("zones.notePlaceholder")}
        maxLength={256}
      />
    </div>
  );
}

/** True when the block is complete enough to save. */
export function parkingIsValid(value: ZoneParkingInput): boolean {
  // "Paid" chosen but no amount typed yet. Saving now would silently store a free spot, so the
  // operator has to finish the thought.
  if (value.parkingFee === null) {
    return false;
  }
  if (value.open24x7 === false) {
    return Boolean(value.opensAt && value.closesAt);
  }
  return true;
}
