import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "wouter";
import { useQueryClient } from "@tanstack/react-query";
import {
  useListMyServiceOrders,
  getListMyServiceOrdersQueryKey,
  useUpdateServiceOrderStatus,
  useDeleteServiceOrder,
  type ServiceOrder,
  type ServiceOrderStatus,
} from "@workspace/api-client-react";
import {
  ArrowLeft,
  ArrowRight,
  ImageIcon,
  Inbox,
  Check,
  Clock,
  Flame,
  PackageCheck,
  XCircle,
  Trash2,
  RotateCcw,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { OrderServiceModal } from "@/components/order-service-modal";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { ToastAction } from "@/components/ui/toast";
import { resolveServiceImageUrl } from "@/lib/image-url";
import { useToast } from "@/hooks/use-toast";
import { formatDateTime } from "@/lib/i18n-format";
import { cn } from "@/lib/utils";

const TIMELINE_STEPS: ServiceOrderStatus[] = [
  "pending",
  "received",
  "preparing",
  "completed",
];

const STATUS_PILL: Record<ServiceOrderStatus, string> = {
  pending: "bg-slate-200 text-slate-700",
  received: "bg-sky-100 text-sky-700",
  preparing: "bg-amber-100 text-amber-800",
  completed: "bg-emerald-100 text-emerald-700",
  cancelled: "bg-rose-100 text-rose-700",
};

const UNDO_WINDOW_MS = 7000;

function isFinished(status: ServiceOrderStatus) {
  return status === "completed" || status === "cancelled";
}

function StatusPill({ status }: { status: ServiceOrderStatus }) {
  const { t } = useTranslation();
  return (
    <span
      className={cn(
        "inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium",
        STATUS_PILL[status],
      )}
    >
      {t(`orderStatus.${status}`)}
    </span>
  );
}

function StatusTimeline({ status }: { status: ServiceOrderStatus }) {
  const { t } = useTranslation();
  if (status === "cancelled") {
    return (
      <div className="flex items-center justify-center">
        <span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full bg-rose-100 text-rose-700 text-xs font-semibold">
          <XCircle size={14} />
          {t("orderStatus.cancelled")}
        </span>
      </div>
    );
  }
  const currentIdx = TIMELINE_STEPS.indexOf(status);
  return (
    <div className="flex items-center gap-1 w-full">
      {TIMELINE_STEPS.map((step, i) => {
        const reached = i <= currentIdx;
        const Icon =
          step === "pending"
            ? Clock
            : step === "received"
              ? Check
              : step === "preparing"
                ? Flame
                : PackageCheck;
        return (
          <div key={step} className="flex items-center flex-1 min-w-0 last:flex-initial">
            <div
              className={cn(
                "h-7 w-7 rounded-full flex items-center justify-center shrink-0 border",
                reached
                  ? "bg-primary text-primary-foreground border-primary"
                  : "bg-slate-100 text-slate-400 border-slate-200",
              )}
              title={t(`orderStatus.${step}`)}
              aria-label={t(`orderStatus.${step}`)}
            >
              <Icon size={14} />
            </div>
            {i < TIMELINE_STEPS.length - 1 && (
              <div
                className={cn(
                  "h-0.5 flex-1 mx-1 rounded",
                  i < currentIdx ? "bg-primary" : "bg-slate-200",
                )}
              />
            )}
          </div>
        );
      })}
    </div>
  );
}

function OrderImage({
  src,
  alt,
}: {
  src: string | null;
  alt: string;
}) {
  const [errored, setErrored] = useState(false);
  if (!src || errored) {
    return (
      <div className="w-16 h-16 rounded-lg bg-slate-100 flex items-center justify-center shrink-0">
        <ImageIcon size={20} className="text-slate-300" />
      </div>
    );
  }
  return (
    <img
      src={src}
      alt={alt}
      className="w-16 h-16 rounded-lg object-cover shrink-0"
      onError={() => setErrored(true)}
    />
  );
}

function OrderCard({
  order,
  onDelete,
  onReorder,
}: {
  order: ServiceOrder;
  onDelete: (id: number) => void;
  onReorder: (order: ServiceOrder) => void;
}) {
  const { t, i18n } = useTranslation();
  const queryClient = useQueryClient();
  const { toast } = useToast();
  const lang = i18n.language;
  const [confirmCancelOpen, setConfirmCancelOpen] = useState(false);
  const [confirmDeleteOpen, setConfirmDeleteOpen] = useState(false);
  const updateStatus = useUpdateServiceOrderStatus();

  const name = lang === "ar" ? order.service.nameAr : order.service.nameEn;
  const img = resolveServiceImageUrl(order.service.imageUrl);
  const cancellable =
    order.status === "pending" || order.status === "received";
  const finished = isFinished(order.status);
  const deletable = finished;
  const reorderable = finished;

  const handleCancel = () => {
    const previousStatus = order.status;
    updateStatus.mutate(
      { id: order.id, data: { status: "cancelled" } },
      {
        onSuccess: () => {
          queryClient.invalidateQueries({
            queryKey: getListMyServiceOrdersQueryKey(),
          });
          setConfirmCancelOpen(false);

          const undo = () => {
            updateStatus.mutate(
              { id: order.id, data: { status: previousStatus } },
              {
                onSuccess: () => {
                  queryClient.invalidateQueries({
                    queryKey: getListMyServiceOrdersQueryKey(),
                  });
                  handle.dismiss();
                  toast({ title: t("myOrders.undone") });
                },
                onError: () => {
                  toast({
                    title: t("myOrders.restoreFailed"),
                    variant: "destructive",
                  });
                },
              },
            );
          };

          const handle = toast({
            title: t("myOrders.cancelled"),
            duration: UNDO_WINDOW_MS,
            action: (
              <ToastAction altText={t("myOrders.undo")} onClick={undo}>
                {t("myOrders.undo")}
              </ToastAction>
            ),
          });
        },
        onError: () => {
          toast({
            title: t("myOrders.cancelFailed"),
            variant: "destructive",
          });
        },
      },
    );
  };

  const handleDelete = () => {
    setConfirmDeleteOpen(false);
    onDelete(order.id);
  };

  return (
    <div className="glass-panel rounded-xl p-4 flex flex-col gap-3">
      <div className="flex items-start gap-3">
        <OrderImage src={img} alt={name} />
        <div className="flex-1 min-w-0">
          <div className="flex items-start justify-between gap-2">
            <h3 className="text-sm font-semibold text-foreground truncate">
              {name}
            </h3>
            <StatusPill status={order.status} />
          </div>
          <div className="text-[11px] text-muted-foreground mt-0.5">
            {formatDateTime(order.createdAt, lang)}
          </div>
          {order.notes && (
            <div className="mt-1.5 text-xs text-muted-foreground">
              <span className="font-medium text-foreground/80">
                {t("myOrders.notesLabel")}{" "}
              </span>
              {order.notes}
            </div>
          )}
        </div>
      </div>

      <StatusTimeline status={order.status} />

      {(cancellable || finished) && (
        <div className="flex justify-end gap-1">
          {reorderable && (
            <Button
              variant="ghost"
              size="sm"
              className="text-primary hover:text-primary hover:bg-primary/10 gap-1.5"
              onClick={() => onReorder(order)}
            >
              <RotateCcw size={14} />
              {t("myOrders.reorder")}
            </Button>
          )}
          {cancellable && (
            <Button
              variant="ghost"
              size="sm"
              className="text-rose-700 hover:text-rose-800 hover:bg-rose-50"
              onClick={() => setConfirmCancelOpen(true)}
              disabled={updateStatus.isPending}
            >
              {t("myOrders.cancel")}
            </Button>
          )}
          {deletable && (
            <Button
              variant="ghost"
              size="sm"
              className="text-slate-500 hover:text-rose-700 hover:bg-rose-50"
              onClick={() => setConfirmDeleteOpen(true)}
              aria-label={t("myOrders.delete")}
              title={t("myOrders.delete")}
            >
              <Trash2 size={16} />
            </Button>
          )}
        </div>
      )}

      <AlertDialog open={confirmCancelOpen} onOpenChange={setConfirmCancelOpen}>
        <AlertDialogContent dir={lang === "ar" ? "rtl" : "ltr"}>
          <AlertDialogHeader>
            <AlertDialogTitle>
              {t("myOrders.cancelConfirmTitle")}
            </AlertDialogTitle>
            <AlertDialogDescription>
              {t("myOrders.cancelConfirmBody")}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={updateStatus.isPending}>
              {t("myOrders.keep")}
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={(e) => {
                e.preventDefault();
                handleCancel();
              }}
              disabled={updateStatus.isPending}
              className="bg-rose-600 hover:bg-rose-700 text-white"
            >
              {t("myOrders.cancelConfirm")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog open={confirmDeleteOpen} onOpenChange={setConfirmDeleteOpen}>
        <AlertDialogContent dir={lang === "ar" ? "rtl" : "ltr"}>
          <AlertDialogHeader>
            <AlertDialogTitle>
              {t("myOrders.deleteConfirmTitle")}
            </AlertDialogTitle>
            <AlertDialogDescription>
              {t("myOrders.deleteConfirmBody")}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>
              {t("myOrders.keep")}
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={(e) => {
                e.preventDefault();
                handleDelete();
              }}
              className="bg-rose-600 hover:bg-rose-700 text-white"
            >
              {t("myOrders.deleteConfirm")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

export default function MyOrdersPage() {
  const { t, i18n } = useTranslation();
  const [, setLocation] = useLocation();
  const queryClient = useQueryClient();
  const { toast } = useToast();
  const lang = i18n.language;
  const isRtl = lang === "ar";
  const BackIcon = isRtl ? ArrowRight : ArrowLeft;
  const [confirmClearOpen, setConfirmClearOpen] = useState(false);
  const deleteOrder = useDeleteServiceOrder();
  const [pendingDeleteIds, setPendingDeleteIds] = useState<Set<number>>(
    () => new Set(),
  );
  const [reorderTarget, setReorderTarget] = useState<{
    service: {
      id: number;
      nameAr: string;
      nameEn: string;
      imageUrl?: string | null;
    };
    notes: string | null;
  } | null>(null);

  // Track scheduled timers and queued IDs so we can flush on unmount.
  const timersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(
    new Map(),
  );

  const { data: orders, isLoading, isError, refetch } = useListMyServiceOrders({
    query: { queryKey: getListMyServiceOrdersQueryKey() },
  });

  const performDelete = async (ids: number[]) => {
    let okCount = 0;
    let failCount = 0;
    for (const id of ids) {
      try {
        await deleteOrder.mutateAsync({ id });
        okCount += 1;
      } catch {
        failCount += 1;
      }
    }
    queryClient.invalidateQueries({
      queryKey: getListMyServiceOrdersQueryKey(),
    });
    return { okCount, failCount };
  };

  // On unmount, flush any pending deletions so they aren't silently lost.
  useEffect(() => {
    return () => {
      const pending: number[] = [];
      timersRef.current.forEach((timer, id) => {
        clearTimeout(timer);
        pending.push(id);
      });
      timersRef.current.clear();
      if (pending.length > 0) {
        // Fire-and-forget; the page is unmounting.
        void performDelete(pending);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const scheduleDelete = (ids: number[]) => {
    if (ids.length === 0) return;

    setPendingDeleteIds((prev) => {
      const next = new Set(prev);
      ids.forEach((id) => next.add(id));
      return next;
    });

    const timer = setTimeout(() => {
      ids.forEach((id) => timersRef.current.delete(id));
      void performDelete(ids).then(({ failCount }) => {
        if (failCount > 0) {
          // Restore failed deletions on error so the user sees them again.
          setPendingDeleteIds((prev) => {
            const next = new Set(prev);
            ids.forEach((id) => next.delete(id));
            return next;
          });
          toast({
            title: t("myOrders.deleteFailed"),
            variant: "destructive",
          });
        } else {
          setPendingDeleteIds((prev) => {
            const next = new Set(prev);
            ids.forEach((id) => next.delete(id));
            return next;
          });
        }
      });
    }, UNDO_WINDOW_MS);

    ids.forEach((id) => timersRef.current.set(id, timer));

    const undo = () => {
      ids.forEach((id) => {
        const existing = timersRef.current.get(id);
        if (existing) clearTimeout(existing);
        timersRef.current.delete(id);
      });
      setPendingDeleteIds((prev) => {
        const next = new Set(prev);
        ids.forEach((id) => next.delete(id));
        return next;
      });
      handle.dismiss();
      toast({ title: t("myOrders.undone") });
    };

    const title =
      ids.length === 1
        ? t("myOrders.deleted")
        : t("myOrders.clearedCount", { count: ids.length });

    const handle = toast({
      title,
      duration: UNDO_WINDOW_MS,
      action: (
        <ToastAction altText={t("myOrders.undo")} onClick={undo}>
          {t("myOrders.undo")}
        </ToastAction>
      ),
    });
  };

  const sortedOrders = orders
    ? [...orders]
        .filter((o) => !pendingDeleteIds.has(o.id))
        .sort(
          (a, b) =>
            new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
        )
    : [];

  const finishedOrders = sortedOrders.filter((o) => isFinished(o.status));
  const finishedCount = finishedOrders.length;

  const handleClearFinished = () => {
    setConfirmClearOpen(false);
    scheduleDelete(finishedOrders.map((o) => o.id));
  };

  return (
    <div className="min-h-screen os-bg flex flex-col">
      <div className="glass-panel border-b border-slate-200/70 px-4 py-4 flex items-center gap-3 sticky top-0 z-10">
        <button
          onClick={() => setLocation("/services")}
          className="p-2 rounded-xl hover:bg-slate-100 text-muted-foreground hover:text-foreground transition-colors"
          aria-label={t("myOrders.back")}
        >
          <BackIcon size={20} />
        </button>
        <div className="flex items-center gap-2">
          <Inbox size={20} className="text-amber-400" />
          <h1 className="text-lg font-semibold text-foreground">
            {t("myOrders.title")}
          </h1>
        </div>
      </div>

      <div className="flex-1 p-4 pb-8 max-w-2xl mx-auto w-full">
        {isLoading ? (
          <div className="flex items-center justify-center py-20 text-muted-foreground">
            {t("common.loading")}
          </div>
        ) : isError ? (
          <div className="flex flex-col items-center justify-center py-20 gap-3 text-center">
            <div className="text-sm text-rose-700">
              {t("myOrders.loadError")}
            </div>
            <Button variant="outline" size="sm" onClick={() => refetch()}>
              {t("myOrders.retry")}
            </Button>
          </div>
        ) : !sortedOrders.length ? (
          <div className="flex flex-col items-center justify-center py-20 gap-3 text-center">
            <Inbox size={36} className="text-slate-300" />
            <div className="text-sm font-medium text-foreground">
              {t("myOrders.empty")}
            </div>
            <div className="text-xs text-muted-foreground">
              {t("myOrders.emptyHint")}
            </div>
            <Button
              variant="outline"
              size="sm"
              onClick={() => setLocation("/services")}
            >
              {t("myOrders.browseServices")}
            </Button>
          </div>
        ) : (
          <div className="flex flex-col gap-3">
            {finishedCount > 0 && (
              <div className="flex justify-end">
                <Button
                  variant="ghost"
                  size="sm"
                  className="text-slate-600 hover:text-rose-700 hover:bg-rose-50 gap-1.5"
                  onClick={() => setConfirmClearOpen(true)}
                >
                  <Trash2 size={14} />
                  {t("myOrders.clearFinished", { count: finishedCount })}
                </Button>
              </div>
            )}
            {sortedOrders.map((o) => (
              <OrderCard
                key={o.id}
                order={o}
                onDelete={(id) => scheduleDelete([id])}
                onReorder={(order) =>
                  setReorderTarget({
                    service: {
                      id: order.service.id,
                      nameAr: order.service.nameAr,
                      nameEn: order.service.nameEn,
                      imageUrl: order.service.imageUrl,
                    },
                    notes: order.notes ?? null,
                  })
                }
              />
            ))}
          </div>
        )}
      </div>

      <AlertDialog open={confirmClearOpen} onOpenChange={setConfirmClearOpen}>
        <AlertDialogContent dir={lang === "ar" ? "rtl" : "ltr"}>
          <AlertDialogHeader>
            <AlertDialogTitle>
              {t("myOrders.clearConfirmTitle")}
            </AlertDialogTitle>
            <AlertDialogDescription>
              {t("myOrders.clearConfirmBody", { count: finishedCount })}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>
              {t("myOrders.keep")}
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={(e) => {
                e.preventDefault();
                handleClearFinished();
              }}
              className="bg-rose-600 hover:bg-rose-700 text-white"
            >
              {t("myOrders.clearConfirm")}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <OrderServiceModal
        open={reorderTarget !== null}
        onOpenChange={(o) => {
          if (!o) setReorderTarget(null);
        }}
        service={reorderTarget?.service ?? null}
        resolveImage={resolveServiceImageUrl}
        initialNotes={reorderTarget?.notes ?? null}
      />
    </div>
  );
}
