import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "wouter";
import { useQueryClient } from "@tanstack/react-query";
import {
  useListIncomingServiceOrders,
  getListIncomingServiceOrdersQueryKey,
  useConfirmServiceOrderReceipt,
  useUpdateServiceOrderStatus,
  type ServiceOrder,
} from "@workspace/api-client-react";
import {
  ArrowLeft,
  ArrowRight,
  Inbox,
  ImageIcon,
  Clock,
  CheckCheck,
  Flame,
  PackageCheck,
  XCircle,
  Loader2,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { ToastAction } from "@/components/ui/toast";
import { useAuth } from "@/contexts/AuthContext";
import { useToast } from "@/hooks/use-toast";
import { resolveServiceImageUrl } from "@/lib/image-url";
import { cn } from "@/lib/utils";

export const ORDER_RECEIVER_ROLE = "order_receiver";

const UNDO_WINDOW_MS = 7000;

export function userCanReceiveOrders(roles: string[] | undefined | null): boolean {
  if (!roles) return false;
  return roles.includes("admin") || roles.includes(ORDER_RECEIVER_ROLE);
}

function relativeAge(iso: string, t: (k: string, o?: Record<string, unknown>) => string): string {
  const ms = Date.now() - new Date(iso).getTime();
  const mins = Math.max(0, Math.floor(ms / 60000));
  if (mins < 1) return t("incomingOrders.ageJustNow");
  if (mins < 60) return t("incomingOrders.ageMinutes", { count: mins });
  const hours = Math.floor(mins / 60);
  if (hours < 24) return t("incomingOrders.ageHours", { count: hours });
  const days = Math.floor(hours / 24);
  return t("incomingOrders.ageDays", { count: days });
}

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

function StatusIcon({ status }: { status: ServiceOrder["status"] }) {
  const cls = "shrink-0";
  if (status === "pending") return <Clock size={14} className={cn(cls, "text-slate-500")} />;
  if (status === "received") return <CheckCheck size={14} className={cn(cls, "text-sky-600")} />;
  if (status === "preparing") return <Flame size={14} className={cn(cls, "text-amber-600")} />;
  if (status === "completed") return <PackageCheck size={14} className={cn(cls, "text-emerald-600")} />;
  return <XCircle size={14} className={cn(cls, "text-rose-600")} />;
}

function IncomingOrderCard({
  order,
  meId,
  onActionDone,
}: {
  order: ServiceOrder;
  meId: number;
  onActionDone: () => void;
}) {
  const { t, i18n } = useTranslation();
  const lang = i18n.language;
  const { toast } = useToast();
  const queryClient = useQueryClient();

  const claim = useConfirmServiceOrderReceipt();
  const updateStatus = useUpdateServiceOrderStatus();

  const isMine = order.assignedTo === meId;
  const serviceName = lang === "ar" ? order.service.nameAr : order.service.nameEn;
  const requesterName = order.requester
    ? lang === "ar"
      ? (order.requester.displayNameAr ?? order.requester.username)
      : (order.requester.displayNameEn ?? order.requester.username)
    : "";
  const img = resolveServiceImageUrl(order.service.imageUrl);
  const busy = claim.isPending || updateStatus.isPending;

  const invalidate = () => {
    queryClient.invalidateQueries({
      queryKey: getListIncomingServiceOrdersQueryKey(),
    });
    onActionDone();
  };

  const handleConfirmReceipt = () => {
    claim.mutate(
      { id: order.id },
      {
        onSuccess: () => {
          toast({ title: t("incomingOrders.claimed") });
          invalidate();
        },
        onError: (err: unknown) => {
          const apiErr = err as { status?: number; data?: { error?: string } } | null;
          const status = apiErr?.status;
          const code = apiErr?.data?.error;
          if (
            (status === 409 && code === "order_unavailable") ||
            status === 404
          ) {
            toast({
              title: t("incomingOrders.orderUnavailable"),
              variant: "destructive",
            });
          } else if (status === 409) {
            toast({
              title: t("incomingOrders.alreadyClaimed"),
              variant: "destructive",
            });
          } else {
            toast({
              title: t("incomingOrders.actionFailed"),
              variant: "destructive",
            });
          }
          invalidate();
        },
      },
    );
  };

  const handleSetStatus = (status: "preparing" | "completed" | "cancelled") => {
    if (status === "cancelled") {
      handleCancel();
      return;
    }
    updateStatus.mutate(
      { id: order.id, data: { status } },
      {
        onSuccess: () => {
          toast({ title: t("incomingOrders.marked") });
          invalidate();
        },
        onError: (err: unknown) => {
          const apiErr = err as { status?: number; data?: { error?: string } } | null;
          if (
            (apiErr?.status === 409 && apiErr?.data?.error === "order_unavailable") ||
            apiErr?.status === 404
          ) {
            toast({
              title: t("incomingOrders.orderUnavailable"),
              variant: "destructive",
            });
            invalidate();
          } else {
            toast({
              title: t("incomingOrders.actionFailed"),
              variant: "destructive",
            });
          }
        },
      },
    );
  };

  const handleCancel = () => {
    const previousStatus = order.status;
    if (previousStatus !== "received" && previousStatus !== "preparing") {
      return;
    }
    updateStatus.mutate(
      { id: order.id, data: { status: "cancelled" } },
      {
        onSuccess: () => {
          invalidate();

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

          const handle = toast({
            title: t("incomingOrders.cancelled"),
            duration: UNDO_WINDOW_MS,
            action: (
              <ToastAction
                altText={t("incomingOrders.undo")}
                onClick={undo}
              >
                {t("incomingOrders.undo")}
              </ToastAction>
            ),
          });
        },
        onError: (err: unknown) => {
          const apiErr = err as { status?: number; data?: { error?: string } } | null;
          if (
            (apiErr?.status === 409 && apiErr?.data?.error === "order_unavailable") ||
            apiErr?.status === 404
          ) {
            toast({
              title: t("incomingOrders.orderUnavailable"),
              variant: "destructive",
            });
            invalidate();
          } else {
            toast({
              title: t("incomingOrders.actionFailed"),
              variant: "destructive",
            });
          }
        },
      },
    );
  };

  return (
    <div className="glass-panel rounded-xl p-3 flex flex-col gap-3">
      <div className="flex items-start gap-3">
        <OrderImage src={img} alt={serviceName} />
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-1.5 text-[11px] text-muted-foreground">
            <StatusIcon status={order.status} />
            <span>{t(`orderStatus.${order.status}`)}</span>
            <span aria-hidden="true">·</span>
            <span>{relativeAge(order.createdAt, t)}</span>
          </div>
          <h3 className="text-sm font-semibold text-foreground leading-tight truncate mt-0.5">
            {serviceName}
          </h3>
          <div className="text-xs text-muted-foreground truncate">
            {t("incomingOrders.from")}{" "}
            <span className="text-foreground/80 font-medium">{requesterName}</span>
          </div>
          {order.notes && (
            <div className="mt-1.5 text-xs text-foreground/80 line-clamp-3 whitespace-pre-wrap">
              {order.notes}
            </div>
          )}
        </div>
      </div>

      <div className="flex flex-wrap gap-2 justify-end">
        {order.status === "pending" && !order.assignedTo && (
          <Button size="sm" onClick={handleConfirmReceipt} disabled={busy}>
            {claim.isPending && <Loader2 size={14} className="animate-spin me-1.5" />}
            {claim.isPending
              ? t("incomingOrders.confirming")
              : t("incomingOrders.confirmReceipt")}
          </Button>
        )}

        {isMine && order.status === "received" && (
          <Button
            size="sm"
            onClick={() => handleSetStatus("preparing")}
            disabled={busy}
          >
            {t("incomingOrders.markPreparing")}
          </Button>
        )}

        {isMine && order.status === "preparing" && (
          <Button
            size="sm"
            onClick={() => handleSetStatus("completed")}
            disabled={busy}
            className="bg-emerald-600 hover:bg-emerald-700 text-white"
          >
            {t("incomingOrders.markCompleted")}
          </Button>
        )}

        {isMine &&
          (order.status === "received" || order.status === "preparing") && (
            <Button
              size="sm"
              variant="ghost"
              className="text-rose-700 hover:text-rose-800 hover:bg-rose-50"
              onClick={() => handleSetStatus("cancelled")}
              disabled={busy}
            >
              {t("incomingOrders.cancel")}
            </Button>
          )}
      </div>
    </div>
  );
}

export default function OrdersIncomingPage() {
  const { t, i18n } = useTranslation();
  const [, setLocation] = useLocation();
  const { user } = useAuth();
  const lang = i18n.language;
  const isRtl = lang === "ar";
  const BackIcon = isRtl ? ArrowRight : ArrowLeft;

  const allowed = userCanReceiveOrders(user?.roles);

  const { data: orders, isLoading, isError, refetch } = useListIncomingServiceOrders({
    query: {
      queryKey: getListIncomingServiceOrdersQueryKey(),
      enabled: !!user && allowed,
    },
  });

  const meId = user?.id ?? -1;
  const sorted = (orders ?? [])
    .slice()
    .sort(
      (a, b) =>
        new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
    );
  const mine = sorted.filter((o) => o.assignedTo === meId);
  const unclaimed = sorted.filter((o) => o.status === "pending" && !o.assignedTo);

  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("/")}
          className="p-2 rounded-xl hover:bg-slate-100 text-muted-foreground hover:text-foreground transition-colors"
          aria-label={t("incomingOrders.back")}
        >
          <BackIcon size={20} />
        </button>
        <div className="flex items-center gap-2">
          <Inbox size={20} className="text-amber-500" />
          <h1 className="text-lg font-semibold text-foreground">
            {t("incomingOrders.title")}
          </h1>
        </div>
      </div>

      <div className="flex-1 p-4 pb-8 max-w-2xl mx-auto w-full">
        {!allowed ? (
          <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("incomingOrders.noAccess")}
            </div>
          </div>
        ) : 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("incomingOrders.loadError")}
            </div>
            <Button variant="outline" size="sm" onClick={() => refetch()}>
              {t("incomingOrders.retry")}
            </Button>
          </div>
        ) : mine.length === 0 && unclaimed.length === 0 ? (
          <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("incomingOrders.empty")}
            </div>
            <div className="text-xs text-muted-foreground">
              {t("incomingOrders.emptyHint")}
            </div>
          </div>
        ) : (
          <div className="flex flex-col gap-6">
            {mine.length > 0 && (
              <section>
                <h2 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2 px-1">
                  {t("incomingOrders.subtitleMine")}
                </h2>
                <div className="flex flex-col gap-2">
                  {mine.map((o) => (
                    <IncomingOrderCard
                      key={o.id}
                      order={o}
                      meId={meId}
                      onActionDone={refetch}
                    />
                  ))}
                </div>
              </section>
            )}
            {unclaimed.length > 0 && (
              <section>
                <h2 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2 px-1">
                  {t("incomingOrders.subtitleUnclaimed")}
                </h2>
                <div className="flex flex-col gap-2">
                  {unclaimed.map((o) => (
                    <IncomingOrderCard
                      key={o.id}
                      order={o}
                      meId={meId}
                      onActionDone={refetch}
                    />
                  ))}
                </div>
              </section>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
