"use client";

import { useState, useRef } from "react";
import { useRouter } from "next/navigation";
import { updateStop } from "@/actions/stops/update-stop";
import { AdminInput, AdminSelect } from "./design-system/AdminFormElements";
import AdminButton from "./design-system/AdminButton";
import { useToast } from "./Toast";

type Brand = {
  id: string;
  name: string;
  slug: string;
};

type StopEditFormProps = {
  stop: {
    id: string;
    city: string;
    state: string;
    date: string;
    time: string;
    location: string;
    slug: string;
    active: boolean;
    brand_id: string;
    address?: string | null;
    zip?: string | null;
    cutoff_time?: string | null;
  };
  brands: Brand[];
  /** Optional callback fired after a successful save. */
  onSaved?: () => void;
};

type DraftSetter<T> = (v: T | ((prev: T) => T)) => void;

export default function StopEditForm({ stop, brands, onSaved }: StopEditFormProps) {
  const router = useRouter();
  const { success: showSuccess, error: showError } = useToast();
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const savedRef = useRef(false);

  // Holds user edits only; missing keys fall back to the current prop so we
  // never copy the prop into useState. When the prop changes, the fallback
  // value tracks the new prop automatically.
  const [draft, setDraft] = useState<{
    city?: string;
    state?: string;
    date?: string;
    time?: string;
    location?: string;
    active?: boolean;
    brand_id?: string;
    address?: string;
    zip?: string;
    cutoff_time?: string;
  }>({});

  const city = draft.city ?? stop.city;
  const state = draft.state ?? stop.state;
  const date = draft.date ?? stop.date;
  const time = draft.time ?? stop.time;
  const location = draft.location ?? stop.location;
  const active = draft.active ?? stop.active;
  const brand_id = draft.brand_id ?? stop.brand_id;
  const address = draft.address ?? stop.address ?? "";
  const zip = draft.zip ?? stop.zip ?? "";
  const cutoff_time = draft.cutoff_time ?? stop.cutoff_time ?? "";

  const setCity: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      city: typeof v === "function" ? v(d.city ?? stop.city) : v,
    }));
  const setState: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      state: typeof v === "function" ? v(d.state ?? stop.state) : v,
    }));
  const setDate: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      date: typeof v === "function" ? v(d.date ?? stop.date) : v,
    }));
  const setTime: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      time: typeof v === "function" ? v(d.time ?? stop.time) : v,
    }));
  const setLocation: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      location: typeof v === "function" ? v(d.location ?? stop.location) : v,
    }));
  const setActive: DraftSetter<boolean> = (v) =>
    setDraft((d) => ({
      ...d,
      active: typeof v === "function" ? v(d.active ?? stop.active) : v,
    }));
  const setBrand_id: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      brand_id: typeof v === "function" ? v(d.brand_id ?? stop.brand_id) : v,
    }));
  const setAddress: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      address: typeof v === "function" ? v(d.address ?? stop.address ?? "") : v,
    }));
  const setZip: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      zip: typeof v === "function" ? v(d.zip ?? stop.zip ?? "") : v,
    }));
  const setCutoff_time: DraftSetter<string> = (v) =>
    setDraft((d) => ({
      ...d,
      cutoff_time:
        typeof v === "function" ? v(d.cutoff_time ?? stop.cutoff_time ?? "") : v,
    }));

  // Validation errors
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});

  function validateForm(): boolean {
    const errors: Record<string, string> = {};

    if (!city.trim()) {
      errors.city = "City is required";
    }
    if (!state.trim()) {
      errors.state = "State is required";
    }
    if (!date.trim()) {
      errors.date = "Date is required";
    }

    setFieldErrors(errors);
    return Object.keys(errors).length === 0;
  }

  async function handleSave() {
    if (!validateForm()) {
      showError("Validation failed", "Please fix the errors below");
      return;
    }

    setSaving(true);
    setError(null);
    savedRef.current = false;

    const result = await updateStop(stop.id, brand_id, {
      city,
      state,
      location,
      date,
      time,
      active,
      address: address || null,
      zip: zip || null,
      cutoff_time: cutoff_time || null,
    });

    if (!result.success) {
      showError("Failed to save", result.error ?? "Please try again");
      setError(result.error ?? "Failed to save");
      setSaving(false);
      return;
    }

    showSuccess("Stop updated", `${city}, ${state} has been saved`);
    savedRef.current = true;
    setSaving(false);
    onSaved?.();
    router.refresh();
  }

  return (
    <div className="space-y-6">
      <FormErrorBanner error={error} />

      <LocationIdentityFields
        city={city}
        state={state}
        date={date}
        time={time}
        fieldErrors={fieldErrors}
        setCity={setCity}
        setState={setState}
        setDate={setDate}
        setTime={setTime}
        clearFieldError={(field) =>
          setFieldErrors((prev) => {
            const next = { ...prev };
            delete next[field];
            return next;
          })
        }
      />

      <AddressFields
        location={location}
        address={address}
        zip={zip}
        setLocation={setLocation}
        setAddress={setAddress}
        setZip={setZip}
      />

      <AdminInput
        label="Order Cutoff"
        helpText="Customers must order before this time to be included at this stop."
      >
        <input aria-label="Datetime Local"
          type="datetime-local"
          value={cutoff_time}
          onChange={(e) => setCutoff_time(e.target.value)}
          className="w-full rounded-xl border border-[var(--admin-border)] bg-white px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20"
        />
      </AdminInput>

      <AdminInput label="Brand">
        <AdminSelect
          value={brand_id}
          onChange={(e) => setBrand_id(e.target.value)}
          options={brands.map((b) => ({ value: b.id, label: b.name }))}
        />
      </AdminInput>

      <StatusToggle active={active} onToggle={() => setActive((v) => !v)} />

      <AdminButton
        onClick={handleSave}
        disabled={saving}
        isLoading={saving}
        variant="primary"
        fullWidth
        size="lg"
      >
        {saving ? "Saving..." : "Save Changes"}
      </AdminButton>
    </div>
  );
}

function FormErrorBanner({ error }: { error: string | null }) {
  if (!error) return null;
  return (
    <div className="rounded-xl bg-red-50 border border-red-200 p-4 text-sm text-red-600 flex items-start gap-3">
      <svg className="h-5 w-5 shrink-0 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
      {error}
    </div>
  );
}

function LocationIdentityFields({
  city,
  state,
  date,
  time,
  fieldErrors,
  setCity,
  setState,
  setDate,
  setTime,
  clearFieldError,
}: {
  city: string;
  state: string;
  date: string;
  time: string;
  fieldErrors: Record<string, string>;
  setCity: DraftSetter<string>;
  setState: DraftSetter<string>;
  setDate: DraftSetter<string>;
  setTime: DraftSetter<string>;
  clearFieldError: (field: string) => void;
}) {
  return (
    <>
      <div className="grid grid-cols-2 gap-4">
        <div>
          <label className="block text-xs font-semibold text-stone-700 mb-1.5" htmlFor="fld-city-">
            City <span className="text-red-500">*</span>
          </label>
          <input id="fld-city-" aria-label="City Name"
            type="text"
            value={city}
            onChange={(e) => {
              setCity(e.target.value);
              clearFieldError("city");
            }}
            placeholder="City name"
            className={`w-full rounded-xl border px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:ring-2 focus:ring-[var(--admin-accent)]/20 ${
              fieldErrors.city
                ? "border-red-400 bg-red-50"
                : "border-[var(--admin-border)] bg-white focus:border-[var(--admin-accent)]"
            }`}
          />
          {fieldErrors.city && <p className="mt-1 text-xs text-red-500">{fieldErrors.city}</p>}
        </div>

        <div>
          <label className="block text-xs font-semibold text-stone-700 mb-1.5" htmlFor="fld-state-">
            State <span className="text-red-500">*</span>
          </label>
          <input id="fld-state-" aria-label="State Code"
            type="text"
            value={state}
            onChange={(e) => {
              setState(e.target.value);
              clearFieldError("state");
            }}
            placeholder="State code"
            className={`w-full rounded-xl border px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:ring-2 focus:ring-[var(--admin-accent)]/20 ${
              fieldErrors.state
                ? "border-red-400 bg-red-50"
                : "border-[var(--admin-border)] bg-white focus:border-[var(--admin-accent)]"
            }`}
          />
          {fieldErrors.state && <p className="mt-1 text-xs text-red-500">{fieldErrors.state}</p>}
        </div>
      </div>

      <div className="grid grid-cols-2 gap-4">
        <div>
          <label className="block text-xs font-semibold text-stone-700 mb-1.5" htmlFor="fld-date-">
            Date <span className="text-red-500">*</span>
          </label>
          <input id="fld-date-" aria-label="Date"
            type="date"
            value={date}
            onChange={(e) => {
              setDate(e.target.value);
              clearFieldError("date");
            }}
            className={`w-full rounded-xl border px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:ring-2 focus:ring-[var(--admin-accent)]/20 ${
              fieldErrors.date
                ? "border-red-400 bg-red-50"
                : "border-[var(--admin-border)] bg-white focus:border-[var(--admin-accent)]"
            }`}
          />
          {fieldErrors.date && <p className="mt-1 text-xs text-red-500">{fieldErrors.date}</p>}
        </div>

        <div>
          <label htmlFor="fld-1-time" className="block text-xs font-semibold text-stone-700 mb-1.5">Time</label>
          <input id="fld-1-time" aria-label=". 8:00 AM – 2:00 PM"
            type="text"
            value={time}
            onChange={(e) => setTime(e.target.value)}
            placeholder="e.g. 8:00 AM – 2:00 PM"
            className="w-full rounded-xl border border-[var(--admin-border)] bg-white px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20"
          />
        </div>
      </div>
    </>
  );
}

function AddressFields({
  location,
  address,
  zip,
  setLocation,
  setAddress,
  setZip,
}: {
  location: string;
  address: string;
  zip: string;
  setLocation: DraftSetter<string>;
  setAddress: DraftSetter<string>;
  setZip: DraftSetter<string>;
}) {
  return (
    <>
      <div>
        <label htmlFor="fld-2-location-name" className="block text-xs font-semibold text-stone-700 mb-1.5">Location Name</label>
        <input id="fld-2-location-name" aria-label="Street Address Or Intersection"
          type="text"
          value={location}
          onChange={(e) => setLocation(e.target.value)}
          placeholder="Street address or intersection"
          className="w-full rounded-xl border border-[var(--admin-border)] bg-white px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20"
        />
      </div>

      <div className="grid grid-cols-2 gap-4">
        <div>
          <label htmlFor="fld-3-street-address" className="block text-xs font-semibold text-stone-700 mb-1.5">Street Address</label>
          <input id="fld-3-street-address" aria-label="123 Main St"
            type="text"
            value={address}
            onChange={(e) => setAddress(e.target.value)}
            placeholder="123 Main St"
            className="w-full rounded-xl border border-[var(--admin-border)] bg-white px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20"
          />
        </div>

        <div>
          <label htmlFor="fld-4-zip-code" className="block text-xs font-semibold text-stone-700 mb-1.5">ZIP Code</label>
          <input id="fld-4-zip-code" aria-label="80102"
            type="text"
            value={zip}
            onChange={(e) => setZip(e.target.value)}
            placeholder="80102"
            maxLength={10}
            className="w-full rounded-xl border border-[var(--admin-border)] bg-white px-3 py-2.5 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20"
          />
        </div>
      </div>
    </>
  );
}

function StatusToggle({ active, onToggle }: { active: boolean; onToggle: () => void }) {
  return (
    <div>
      <label className="mb-2 block text-sm font-medium text-stone-700">
        <span className="block mb-2">Status</span>
        <button
          type="button"
          onClick={onToggle}
          className={`w-full rounded-xl px-4 py-3 text-sm font-medium transition-colors ${
            active
              ? "bg-green-100 text-green-700 border border-green-200"
              : "bg-stone-100 text-stone-500 border border-stone-200 hover:bg-stone-50"
          }`}
        >
          <span aria-hidden="true">{active ? "✓ " : "○ "}</span>
          {active ? "Active — visible on storefront" : "Inactive — hidden from storefront"}
        </button>
      </label>
    </div>
  );
}
