"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useParams, useSearchParams } from "next/navigation";
import { PageLayout } from "@/components/templates/PageLayout";
import {
  ClipboardDocumentCheckIcon,
  CheckCircleIcon,
  WifiIcon,
  DevicePhoneMobileIcon,
  LockClosedIcon,
  CubeIcon,
  SparklesIcon,
  WrenchScrewdriverIcon,
  PuzzlePieceIcon,
  BoltIcon,
  ClockIcon,
  Squares2X2Icon,
  ExclamationTriangleIcon,
  ArrowLeftIcon,
} from "@heroicons/react/24/outline";
import { StatusPill } from "@/components/atoms/status-pill";
import { Button } from "@/components/atoms/button";
import { ordersService } from "@/features/orders/services/orders.service";
import { useOrderUpdates } from "@/features/orders/hooks/useOrderUpdates";
import {
  calculateOrderTotals,
  deriveOrderStatusDescriptor,
  getServiceCategory,
} from "@/features/orders/utils/order-presenters";
import {
  buildOrderDisplayItems,
  type OrderDisplayItem,
  type OrderDisplayItemCategory,
  type OrderDisplayItemCharge,
} from "@/features/orders/utils/order-display";
import type { OrderDetails, OrderUpdateEventPayload } from "@customer-portal/domain/orders";
import { cn } from "@/lib/utils/cn";

const STATUS_PILL_VARIANT: Record<
  "success" | "info" | "warning" | "neutral",
  "success" | "info" | "warning" | "neutral"
> = {
  success: "success",
  info: "info",
  warning: "warning",
  neutral: "neutral",
};

const renderServiceIcon = (category: ReturnType<typeof getServiceCategory>, className: string) => {
  switch (category) {
    case "internet":
      return <WifiIcon className={className} />;
    case "sim":
      return <DevicePhoneMobileIcon className={className} />;
    case "vpn":
      return <LockClosedIcon className={className} />;
    default:
      return <CubeIcon className={className} />;
  }
};

const CATEGORY_CONFIG: Record<
  OrderDisplayItemCategory,
  {
    icon: typeof SparklesIcon;
    label: string;
  }
> = {
  service: {
    icon: SparklesIcon,
    label: "Service",
  },
  installation: {
    icon: WrenchScrewdriverIcon,
    label: "Installation",
  },
  addon: {
    icon: PuzzlePieceIcon,
    label: "Add-on",
  },
  activation: {
    icon: BoltIcon,
    label: "Activation",
  },
  other: {
    icon: Squares2X2Icon,
    label: "Item",
  },
};

const ITEM_VISUAL_STYLES: Record<
  OrderDisplayItemCategory,
  {
    container: string;
    icon: string;
  }
> = {
  service: {
    container: "border-blue-200 bg-white",
    icon: "bg-blue-50 text-blue-600",
  },
  installation: {
    container: "border-green-200 bg-white",
    icon: "bg-green-50 text-green-600",
  },
  addon: {
    container: "border-purple-200 bg-white",
    icon: "bg-purple-50 text-purple-600",
  },
  activation: {
    container: "border-green-200 bg-white",
    icon: "bg-green-50 text-green-600",
  },
  other: {
    container: "border-slate-200 bg-white",
    icon: "bg-slate-50 text-slate-600",
  },
};

const getItemVisualStyle = (item: OrderDisplayItem) => {
  return ITEM_VISUAL_STYLES[item.primaryCategory] ?? ITEM_VISUAL_STYLES.other;
};

const describeCharge = (charge: OrderDisplayItemCharge): string => {
  if (typeof charge.suffix === "string" && charge.suffix.trim().length > 0) {
    return charge.suffix.trim();
  }

  if (charge.kind === "one-time") {
    return "one-time";
  }

  if (charge.kind === "monthly") {
    return "/ month";
  }

  return charge.label.toLowerCase();
};

const yenFormatter = new Intl.NumberFormat("ja-JP", {
  style: "currency",
  currency: "JPY",
  maximumFractionDigits: 0,
});

export function OrderDetailContainer() {
  const params = useParams<{ id: string }>();
  const searchParams = useSearchParams();
  const [data, setData] = useState<OrderDetails | null>(null);
  const [error, setError] = useState<string | null>(null);
  const isNewOrder = searchParams.get("status") === "success";
  const activeControllerRef = useRef<AbortController | null>(null);
  const isMountedRef = useRef(true);

  const statusDescriptor = data
    ? deriveOrderStatusDescriptor({
        status: data.status,
        activationStatus: data.activationStatus,
        scheduledAt: data.activationScheduledAt,
      })
    : null;

  const statusPillVariant = statusDescriptor
    ? STATUS_PILL_VARIANT[statusDescriptor.tone]
    : STATUS_PILL_VARIANT.neutral;

  const serviceCategory = getServiceCategory(data?.orderType);
  const serviceIcon = renderServiceIcon(serviceCategory, "h-6 w-6");

  const displayItems = useMemo<OrderDisplayItem[]>(() => {
    return buildOrderDisplayItems(data?.itemsSummary);
  }, [data?.itemsSummary]);

  const totals = useMemo(
    () =>
      calculateOrderTotals(
        data?.itemsSummary?.map(item => ({
          totalPrice: item.totalPrice,
          billingCycle: item.billingCycle,
        })),
        data?.totalAmount
      ),
    [data?.itemsSummary, data?.totalAmount]
  );

  const placedDate = useMemo(() => {
    if (!data?.createdDate) return null;
    const date = new Date(data.createdDate);
    if (Number.isNaN(date.getTime())) return null;
    return date.toLocaleDateString("en-US", {
      weekday: "long",
      month: "long",
      day: "numeric",
      year: "numeric",
    });
  }, [data?.createdDate]);

  const serviceLabel = useMemo(() => {
    switch (serviceCategory) {
      case "internet":
        return "Internet Service";
      case "sim":
        return "Mobile Service";
      case "vpn":
        return "VPN Service";
      default:
        return data?.orderType ? `${data.orderType} Service` : "Service";
    }
  }, [data?.orderType, serviceCategory]);

  const showFeeNotice = displayItems.some(
    item => item.categories.includes("installation") || item.categories.includes("activation")
  );

  const fetchOrder = useCallback(async (): Promise<void> => {
    if (!params.id) {
      return;
    }

    if (activeControllerRef.current) {
      activeControllerRef.current.abort();
    }

    const controller = new AbortController();
    activeControllerRef.current = controller;

    try {
      const order = await ordersService.getOrderById(params.id, { signal: controller.signal });
      if (!isMountedRef.current || controller.signal.aborted) {
        return;
      }
      setData(order ?? null);
      setError(null);
    } catch (e) {
      if (!isMountedRef.current || controller.signal.aborted) {
        return;
      }
      setError(e instanceof Error ? e.message : "Failed to load order");
    } finally {
      if (activeControllerRef.current === controller) {
        activeControllerRef.current = null;
      }
    }
  }, [params.id]);

  useEffect(() => {
    isMountedRef.current = true;
    void fetchOrder();

    return () => {
      isMountedRef.current = false;
      if (activeControllerRef.current) {
        activeControllerRef.current.abort();
        activeControllerRef.current = null;
      }
    };
  }, [fetchOrder]);

  const handleOrderUpdate = useCallback(
    (event: OrderUpdateEventPayload) => {
      if (!params.id || event.orderId !== params.id) {
        return;
      }
      void fetchOrder();
    },
    [fetchOrder, params.id]
  );

  useOrderUpdates(params.id, handleOrderUpdate);

  return (
    <PageLayout
      icon={<ClipboardDocumentCheckIcon />}
      title={data ? `${data.orderType} Service Order` : "Order Details"}
      description={
        data
          ? `Order #${data.orderNumber || String(data.id).slice(-8)}`
          : "Loading order details..."
      }
    >
      <div className="mb-6">
        <Button
          as="a"
          href="/orders"
          size="sm"
          variant="ghost"
          leftIcon={<ArrowLeftIcon className="h-4 w-4" />}
          className="text-gray-600 hover:text-gray-900"
        >
          Back to orders
        </Button>
      </div>

      {error && <div className="mb-4 text-sm text-red-600">{error}</div>}

      {isNewOrder && (
        <div className="mb-6 rounded-2xl border border-green-200 bg-green-50 px-5 py-4 shadow-sm">
          <div className="flex items-start gap-3">
            <CheckCircleIcon className="h-6 w-6 text-green-600" />
            <div className="space-y-3">
              <div>
                <h3 className="text-lg font-semibold text-green-900">Order Submitted!</h3>
                <p className="text-sm text-green-800">
                  We&apos;ve received your order and started the review process. Status updates will
                  appear here automatically.
                </p>
              </div>
              <ul className="list-disc space-y-1 pl-5 text-sm text-green-700">
                <li>We&apos;ll confirm everything within 1 business day.</li>
                <li>You&apos;ll get an email as soon as the order is approved.</li>
                <li>Installation scheduling happens right after approval.</li>
              </ul>
            </div>
          </div>
        </div>
      )}

      {data ? (
        <>
          <div className="rounded-3xl border border-slate-200 bg-white shadow-sm">
            {/* Header Section */}
            <div className="border-b border-slate-200 bg-gradient-to-br from-white to-slate-50 px-6 py-6 sm:px-8">
              <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                {/* Left: Title & Date */}
                <div className="flex flex-col gap-1">
                  <div className="flex items-center gap-3">
                    <div className="flex h-11 w-11 items-center justify-center rounded-xl bg-slate-100 text-slate-600">
                      {serviceIcon}
                    </div>
                    <div>
                      <div className="flex items-center gap-2">
                        <h2 className="text-2xl font-bold text-gray-900">{serviceLabel}</h2>
                        {statusDescriptor && (
                          <StatusPill label={statusDescriptor.label} variant={statusPillVariant} />
                        )}
                      </div>
                      {placedDate && <p className="text-sm text-gray-500">{placedDate}</p>}
                    </div>
                  </div>
                </div>

                {/* Right: Pricing Section */}
                <div className="flex items-start gap-6 sm:gap-8">
                  {totals.monthlyTotal > 0 && (
                    <div className="text-right">
                      <p className="mb-1 text-xs font-medium uppercase tracking-wider text-blue-600">
                        Monthly
                      </p>
                      <p className="text-3xl font-bold text-gray-900">
                        {yenFormatter.format(totals.monthlyTotal)}
                      </p>
                    </div>
                  )}
                  {totals.oneTimeTotal > 0 && (
                    <div className="text-right">
                      <p className="mb-1 text-xs font-medium uppercase tracking-wider text-blue-600">
                        One-Time
                      </p>
                      <p className="text-3xl font-bold text-gray-900">
                        {yenFormatter.format(totals.oneTimeTotal)}
                      </p>
                    </div>
                  )}
                </div>
              </div>
            </div>

            <div className="px-6 py-6 sm:px-8">
              <div className="flex flex-col gap-6">
                {/* Order Items Section */}
                <div>
                  <h3
                    className="mb-2 text-xs font-semibold uppercase tracking-widest text-gray-700"
                    style={{ letterSpacing: "0.1em" }}
                  >
                    Order Details
                  </h3>
                  <div className="space-y-4">
                    {displayItems.length === 0 ? (
                      <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-4 py-8 text-center text-sm text-gray-500">
                        No items found on this order.
                      </div>
                    ) : (
                      displayItems.map((item, itemIndex) => {
                        const categoryConfig =
                          CATEGORY_CONFIG[item.primaryCategory] ?? CATEGORY_CONFIG.other;
                        const Icon = categoryConfig.icon;
                        const style = getItemVisualStyle(item);

                        return (
                          <div key={item.id}>
                            <div
                              className={cn(
                                "flex flex-col gap-3 rounded-xl border px-4 py-4 sm:flex-row sm:items-center sm:justify-between",
                                style.container,
                                itemIndex > 0 && "border-t-0 rounded-t-none"
                              )}
                            >
                              {/* Icon + Title & Category | Price */}
                              <div className="flex flex-1 items-start gap-3">
                                <div
                                  className={cn(
                                    "flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-lg",
                                    style.icon
                                  )}
                                >
                                  <Icon className="h-4 w-4" />
                                </div>
                                <div className="flex flex-1 items-baseline justify-between gap-4 sm:items-center">
                                  <div className="min-w-0 flex-1">
                                    <h4 className="font-semibold leading-snug text-gray-900">
                                      {item.name}
                                    </h4>
                                    <p className="mt-0.5 text-xs font-semibold text-gray-600">
                                      {categoryConfig.label}
                                    </p>
                                  </div>
                                  {/* Price - Right aligned */}
                                  <div className="flex flex-col items-end gap-0.5 text-right">
                                    {item.charges.map((charge, index) => {
                                      const descriptor = describeCharge(charge);
                                      if (charge.amount > 0) {
                                        return (
                                          <div
                                            key={`${item.id}-charge-${index}`}
                                            className="whitespace-nowrap text-lg"
                                          >
                                            <span className="font-bold text-gray-900">
                                              {yenFormatter.format(charge.amount)}
                                            </span>
                                            <span className="ml-2 text-xs font-medium text-gray-500">
                                              {descriptor}
                                            </span>
                                          </div>
                                        );
                                      }

                                      return (
                                        <div
                                          key={`${item.id}-charge-${index}`}
                                          className="text-xs font-medium text-gray-500"
                                        >
                                          Included {descriptor}
                                        </div>
                                      );
                                    })}
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        );
                      })
                    )}
                  </div>
                </div>

                {/* Next Steps Section */}
                {statusDescriptor?.nextAction && (
                  <div className="border-l-4 border-blue-500 bg-blue-50 px-4 py-3">
                    <div className="flex items-start gap-3">
                      <ClockIcon className="h-5 w-5 flex-shrink-0 text-blue-600" />
                      <div>
                        <p className="text-sm font-semibold text-blue-900">Next Steps</p>
                        <p className="mt-1 text-sm text-blue-800">{statusDescriptor.nextAction}</p>
                      </div>
                    </div>
                  </div>
                )}

                {showFeeNotice && (
                  <div className="border-l-4 border-amber-500 bg-amber-50 px-4 py-3">
                    <div className="flex items-start gap-3">
                      <ExclamationTriangleIcon className="h-5 w-5 flex-shrink-0 text-amber-600" />
                      <div>
                        <p className="text-sm font-semibold text-amber-900">
                          Installation Fee Notice
                        </p>
                        <p className="mt-1 text-sm text-amber-800">
                          Standard installation is included. Additional charges may apply for
                          weekend scheduling, express service, or specialized equipment
                          installation. Any extra fees will be discussed and approved by you before
                          work begins.
                        </p>
                      </div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        </>
      ) : (
        <div className="rounded-2xl border border-dashed border-gray-200 bg-white/40 p-6 text-sm text-gray-500">
          Loading order details…
        </div>
      )}
    </PageLayout>
  );
}

export default OrderDetailContainer;
