"use client";

import { useState } from "react";
import {
  api,
  MaintenanceReason,
  MaintenanceTicket,
  TicketStatus,
  Vehicle,
} from "@/lib/api";
import { useApi } from "@/hooks/useApi";
import { useLocale } from "@/i18n/LocaleProvider";
import {
  Button,
  Card,
  EmptyState,
  ErrorState,
  Field,
  IconChip,
  PageHeader,
  SegmentedControl,
  Sheet,
  SkeletonCard,
  StatusBadge,
  Tone,
} from "@/components/ui";

const REASONS: MaintenanceReason[] = [
  "LOW_BATTERY",
  "DAMAGE",
  "FAULT",
  "VANDALISM",
  "RECOVERY",
  "OTHER",
];

const statusTone: Record<TicketStatus, Tone> = {
  OPEN: "danger",
  IN_PROGRESS: "warning",
  RESOLVED: "success",
};

const reasonGlyph: Record<MaintenanceReason, string> = {
  LOW_BATTERY: "🔋",
  DAMAGE: "🔧",
  FAULT: "⚠",
  VANDALISM: "✖",
  RECOVERY: "📍",
  OTHER: "•",
};

type Filter = "OPEN" | "ALL";

export default function Page() {
  const { t } = useLocale();
  const [filter, setFilter] = useState<Filter>("OPEN");
  const [opening, setOpening] = useState(false);

  const tickets = useApi<MaintenanceTicket[]>(
    () => api.listTickets({ openOnly: filter === "OPEN" }),
    [filter],
  );

  const openCount = tickets.data?.filter((x) => x.status !== "RESOLVED").length ?? 0;

  return (
    <div>
      <PageHeader
        titleKey="nav.maintenance"
        actions={
          <div className="flex items-center gap-3">
            <SegmentedControl
              value={filter}
              onChange={setFilter}
              options={[
                { value: "OPEN", label: t("maint.filterOpen") },
                { value: "ALL", label: t("maint.filterAll") },
              ]}
            />
            <Button variant="primary" onClick={() => setOpening(true)}>
              {t("maint.open")}
            </Button>
          </div>
        }
      />

      {filter === "OPEN" && openCount > 0 && (
        <p className="mb-4 text-sm text-muted">
          {openCount} {t("maint.outOfService")}
        </p>
      )}

      <TicketList state={tickets} />

      <OpenTicketSheet
        open={opening}
        onClose={() => setOpening(false)}
        onOpened={() => {
          setOpening(false);
          tickets.reload();
        }}
      />
    </div>
  );
}

/* ------------------------------------------------------------------- list */

function TicketList({
  state,
}: {
  state: {
    data: MaintenanceTicket[] | null;
    loading: boolean;
    error: unknown;
    reload: () => void;
  };
}) {
  const { t } = useLocale();

  if (state.loading) return <SkeletonCard rows={5} />;
  if (state.error) return <ErrorState onRetry={state.reload} />;
  if (!state.data?.length) {
    return (
      <EmptyState
        icon={<span className="text-xl">🛠</span>}
        title={t("maint.emptyTitle")}
        description={t("maint.emptyBody")}
      />
    );
  }

  return (
    <div className="space-y-3">
      {state.data.map((ticket) => (
        <TicketRow key={ticket.id} ticket={ticket} onChanged={state.reload} />
      ))}
    </div>
  );
}

function TicketRow({
  ticket,
  onChanged,
}: {
  ticket: MaintenanceTicket;
  onChanged: () => void;
}) {
  const { t } = useLocale();
  const [busy, setBusy] = useState(false);

  const act = async (fn: () => Promise<unknown>) => {
    setBusy(true);
    try {
      await fn();
      onChanged();
    } finally {
      setBusy(false);
    }
  };

  const resolved = ticket.status === "RESOLVED";

  return (
    <Card>
      <div className="flex flex-wrap items-center gap-4">
        <IconChip tone={statusTone[ticket.status]}>{reasonGlyph[ticket.reason]}</IconChip>

        <div className="min-w-[140px] flex-1">
          <div className="font-medium">{ticket.qrCode ?? ticket.scooterId.slice(0, 8)}</div>
          <div className="text-xs text-muted">
            {t(`maint.reason${ticket.reason}`)}
            {ticket.vehicleType ? ` · ${ticket.vehicleType}` : ""}
          </div>
          {ticket.note && <div className="mt-1 text-xs text-muted-dim">{ticket.note}</div>}
        </div>

        <div className="text-xs text-muted">
          {new Date(ticket.openedAt).toLocaleDateString()}
        </div>

        <StatusBadge tone={statusTone[ticket.status]}>
          {t(`maint.status${ticket.status}`)}
        </StatusBadge>

        {!resolved && (
          // Row actions stay secondary: the one brand-yellow action on this screen is "New
          // ticket" in the header. A yellow Resolve per row would multiply down the queue.
          <div className="flex gap-2">
            {ticket.status === "OPEN" && (
              <Button disabled={busy} onClick={() => act(() => api.startTicket(ticket.id))}>
                {t("maint.start")}
              </Button>
            )}
            <Button
              variant="secondary"
              disabled={busy}
              onClick={() => act(() => api.resolveTicket(ticket.id))}
            >
              {t("maint.resolve")}
            </Button>
          </div>
        )}
      </div>
    </Card>
  );
}

/* ------------------------------------------------------------ open a ticket */

function OpenTicketSheet({
  open,
  onClose,
  onOpened,
}: {
  open: boolean;
  onClose: () => void;
  onOpened: () => void;
}) {
  const { t } = useLocale();
  // The backend enforces one live ticket per vehicle; not offering already-down vehicles is
  // clearer than surfacing that conflict after the fact.
  const vehicles = useApi<Vehicle[]>(api.listVehicles, [open]);
  const [scooterId, setScooterId] = useState("");
  const [reason, setReason] = useState<MaintenanceReason>("FAULT");
  const [note, setNote] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const candidates = vehicles.data?.filter((v) => v.status !== "MAINTENANCE") ?? [];

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    setBusy(true);
    setError(null);
    try {
      await api.openTicket({ scooterId, reason, note: note.trim() || undefined });
      setScooterId("");
      setNote("");
      onOpened();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  return (
    <Sheet open={open} onClose={onClose} title={t("maint.open")}>
      <form onSubmit={submit} className="space-y-4">
        <div>
          <label className="field-label">{t("maint.vehicle")}</label>
          {vehicles.loading ? (
            <SkeletonCard rows={1} />
          ) : candidates.length === 0 ? (
            <Card className="text-sm text-muted">{t("maint.noVehicles")}</Card>
          ) : (
            <select
              className="field"
              value={scooterId}
              onChange={(e) => setScooterId(e.target.value)}
              required
            >
              <option value="">{t("maint.pickVehicle")}</option>
              {candidates.map((v) => (
                <option key={v.id} value={v.id}>
                  {v.qrCode} · {v.vehicleType} · {v.batteryPercent}%
                </option>
              ))}
            </select>
          )}
        </div>

        <div>
          <label className="field-label">{t("maint.reason")}</label>
          <SegmentedControl
            value={reason}
            onChange={setReason}
            options={REASONS.map((r) => ({ value: r, label: t(`maint.reason${r}`) }))}
          />
        </div>

        <Field
          label={t("maint.note")}
          value={note}
          onChange={(e) => setNote(e.target.value)}
          placeholder={t("maint.notePlaceholder")}
        />

        {error && (
          <div className="tint tone-danger rounded-card border p-3 text-sm">{error}</div>
        )}

        <div className="flex gap-3">
          <Button
            variant="primary"
            type="submit"
            disabled={busy || !scooterId}
            className="flex-1"
          >
            {busy ? t("common.loading") : t("maint.openConfirm")}
          </Button>
          <Button type="button" onClick={onClose}>
            {t("common.cancel")}
          </Button>
        </div>
      </form>
    </Sheet>
  );
}
