import { Check, Circle, X, Ban, CheckCircle2, XCircle, CheckCheck, Lock } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";

type BookingStatus = "requested" | "accepted" | "declined" | "confirmed" | "completed" | "cancelled";
export type TimelineRole = "school" | "trainer" | "other";

export type TimelineBooking = {
  status: BookingStatus;
  created_at?: string | null;
  accepted_at?: string | null;
  confirmed_at?: string | null;
  completed_at?: string | null;
  cancelled_at?: string | null;
};

export type TimelineActions = {
  onAccept?: () => void;
  onDecline?: () => void;
  onConfirm?: () => void;
  onComplete?: () => void;
  onCancel?: () => void;
};

type Step = {
  key: "requested" | "accepted" | "confirmed" | "completed";
  label: string;
  at: string | null | undefined;
  /** which role is responsible for advancing past this step */
  actor: "school" | "trainer";
  hint: { school: string; trainer: string; other: string };
};

function fmt(at: string | null | undefined) {
  if (!at) return null;
  return new Date(at).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" });
}

const ORDER: Step["key"][] = ["requested", "accepted", "confirmed", "completed"];

export function BookingTimeline({
  booking,
  role,
  actions,
}: {
  booking: TimelineBooking;
  role: TimelineRole;
  actions?: TimelineActions;
}) {
  const terminated = booking.status === "declined" || booking.status === "cancelled";

  const steps: Step[] = [
    {
      key: "requested",
      label: "Requested by school",
      at: booking.created_at,
      actor: "trainer",
      hint: {
        trainer: "Accept or decline this request.",
        school: "Waiting for the trainer to respond.",
        other: "Trainer review pending.",
      },
    },
    {
      key: "accepted",
      label: "Accepted by trainer",
      at: booking.accepted_at,
      actor: "school",
      hint: {
        school: "Confirm the session to lock it in.",
        trainer: "Waiting for the school to confirm.",
        other: "School confirmation pending.",
      },
    },
    {
      key: "confirmed",
      label: "Confirmed by school",
      at: booking.confirmed_at,
      actor: "trainer",
      hint: {
        trainer: "Mark the session completed once delivered.",
        school: "The trainer will mark it complete after delivery.",
        other: "Session scheduled.",
      },
    },
    {
      key: "completed",
      label: "Session completed",
      at: booking.completed_at,
      actor: "trainer",
      hint: { trainer: "", school: "", other: "" },
    },
  ];

  const currentIdx = ORDER.indexOf(booking.status as Step["key"]);
  const reached = (key: Step["key"]) =>
    currentIdx !== -1 && ORDER.indexOf(key) <= currentIdx;

  return (
    <ol className="relative space-y-3 pl-1">
      {steps.map((step, i) => {
        const done = !!step.at || reached(step.key);
        const isCurrent = !terminated && booking.status === step.key && step.key !== "completed";
        const canAct = isCurrent && role === step.actor;
        const waiting = isCurrent && role !== step.actor;

        return (
          <li key={step.key} className="flex items-start gap-3">
            <div className="flex flex-col items-center">
              <div
                className={cn(
                  "flex h-5 w-5 items-center justify-center rounded-full border",
                  done
                    ? "border-primary bg-primary text-primary-foreground"
                    : "border-border bg-background text-muted-foreground",
                  isCurrent && !done && "border-primary ring-2 ring-primary/20",
                )}
              >
                {done ? <Check className="h-3 w-3" /> : <Circle className="h-2 w-2 fill-current" />}
              </div>
              {i < steps.length - 1 && (
                <div className={cn("mt-1 h-6 w-px", done ? "bg-primary/60" : "bg-border")} />
              )}
            </div>
            <div className="flex-1 -mt-0.5 space-y-1.5">
              <div className={cn("text-sm", done ? "text-foreground" : "text-muted-foreground")}>
                {step.label}
              </div>
              {step.at && <div className="text-xs text-muted-foreground">{fmt(step.at)}</div>}

              {isCurrent && (
                <div className="text-xs text-muted-foreground">{step.hint[role]}</div>
              )}

              {canAct && <StepActions stepKey={step.key} actions={actions} />}
              {waiting && (
                <div className="inline-flex items-center gap-1 rounded-md border border-dashed border-border/70 bg-muted/30 px-2 py-1 text-xs text-muted-foreground">
                  <Lock className="h-3 w-3" />
                  Only the {step.actor} can advance this step
                </div>
              )}
            </div>
          </li>
        );
      })}

      {booking.status === "declined" && (
        <li className="flex items-start gap-3">
          <div className="flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground">
            <X className="h-3 w-3" />
          </div>
          <div className="-mt-0.5 text-sm">Declined by trainer</div>
        </li>
      )}
      {booking.status === "cancelled" && (
        <li className="flex items-start gap-3">
          <div className="flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground">
            <Ban className="h-3 w-3" />
          </div>
          <div className="-mt-0.5">
            <div className="text-sm">Cancelled</div>
            {booking.cancelled_at && (
              <div className="text-xs text-muted-foreground">{fmt(booking.cancelled_at)}</div>
            )}
          </div>
        </li>
      )}
    </ol>
  );
}

function StepActions({
  stepKey,
  actions,
}: {
  stepKey: Step["key"];
  actions?: TimelineActions;
}) {
  if (!actions) return null;
  const cancelBtn = actions.onCancel && (
    <Button size="sm" variant="ghost" onClick={actions.onCancel} className="gap-1.5 text-destructive">
      <Ban className="h-4 w-4" /> Cancel
    </Button>
  );

  if (stepKey === "requested") {
    return (
      <div className="flex flex-wrap gap-2 pt-1">
        {actions.onAccept && (
          <Button size="sm" onClick={actions.onAccept} className="gap-1.5">
            <CheckCircle2 className="h-4 w-4" /> Accept
          </Button>
        )}
        {actions.onDecline && (
          <Button size="sm" variant="outline" onClick={actions.onDecline} className="gap-1.5">
            <XCircle className="h-4 w-4" /> Decline
          </Button>
        )}
      </div>
    );
  }
  if (stepKey === "accepted") {
    return (
      <div className="flex flex-wrap gap-2 pt-1">
        {actions.onConfirm && (
          <Button size="sm" onClick={actions.onConfirm} className="gap-1.5">
            <CheckCheck className="h-4 w-4" /> Confirm session
          </Button>
        )}
        {cancelBtn}
      </div>
    );
  }
  if (stepKey === "confirmed") {
    return (
      <div className="flex flex-wrap gap-2 pt-1">
        {actions.onComplete && (
          <Button size="sm" variant="outline" onClick={actions.onComplete} className="gap-1.5">
            <CheckCircle2 className="h-4 w-4" /> Mark completed
          </Button>
        )}
        {cancelBtn}
      </div>
    );
  }
  return null;
}
