"use client";
import {
  createContext,
  useContext,
  useState,
  useCallback,
  useMemo,
} from "react";
import type { Order, OrderStatus, ShippingInfo, DisputeInfo } from "@/components/orders/types";
import { MOCK_ORDERS } from "@/components/orders/mockData";

interface OrderCtx {
  orders: Order[];
  updateOrderStatus: (orderId: string, status: OrderStatus, description: string) => void;
  addTrackingInfo: (orderId: string, tracking: Partial<ShippingInfo>) => void;
  raiseDispute: (orderId: string, dispute: Omit<DisputeInfo, "status" | "createdAt">) => void;
  markReceived: (orderId: string) => void;
  cancelOrder: (orderId: string, reason: string) => void;
  getOrderById: (id: string) => Order | undefined;
  buyerOrders: Order[];
  sellerOrders: Order[];
}

const OrderContext = createContext<OrderCtx>({
  orders: [],
  updateOrderStatus: () => {},
  addTrackingInfo: () => {},
  raiseDispute: () => {},
  markReceived: () => {},
  cancelOrder: () => {},
  getOrderById: () => undefined,
  buyerOrders: [],
  sellerOrders: [],
});

export function OrderProvider({ children }: { children: React.ReactNode }) {
  const [orders, setOrders] = useState<Order[]>(MOCK_ORDERS);

  const updateOrderStatus = useCallback(
    (orderId: string, status: OrderStatus, description: string) => {
      const now = new Date().toISOString();
      setOrders((prev) =>
        prev.map((o) => {
          if (o.id !== orderId) return o;
          return {
            ...o,
            status,
            updatedAt: now,
            timeline: [
              ...o.timeline,
              {
                status,
                timestamp: now,
                description,
                actor: "seller" as const,
              },
            ],
          };
        })
      );
    },
    []
  );

  const addTrackingInfo = useCallback(
    (orderId: string, tracking: Partial<ShippingInfo>) => {
      const now = new Date().toISOString();
      setOrders((prev) =>
        prev.map((o) => {
          if (o.id !== orderId) return o;
          return {
            ...o,
            status: "shipped" as const,
            updatedAt: now,
            shipping: { ...o.shipping, ...tracking },
            timeline: [
              ...o.timeline,
              {
                status: "shipped" as const,
                timestamp: now,
                description: `Package shipped via ${tracking.courierName ?? "courier"}. Tracking: ${tracking.trackingNumber ?? ""}`,
                actor: "seller" as const,
              },
            ],
          };
        })
      );
    },
    []
  );

  const raiseDispute = useCallback(
    (orderId: string, dispute: Omit<DisputeInfo, "status" | "createdAt">) => {
      const now = new Date().toISOString();
      setOrders((prev) =>
        prev.map((o) => {
          if (o.id !== orderId) return o;
          return {
            ...o,
            status: "disputed" as const,
            updatedAt: now,
            dispute: {
              ...dispute,
              status: "open" as const,
              createdAt: now,
            },
            timeline: [
              ...o.timeline,
              {
                status: "disputed" as const,
                timestamp: now,
                description: `Dispute raised: ${dispute.reason}`,
                actor: "buyer" as const,
              },
            ],
          };
        })
      );
    },
    []
  );

  const markReceived = useCallback((orderId: string) => {
    const now = new Date().toISOString();
    setOrders((prev) =>
      prev.map((o) => {
        if (o.id !== orderId) return o;
        return {
          ...o,
          status: "completed" as const,
          updatedAt: now,
          timeline: [
            ...o.timeline,
            {
              status: "completed" as const,
              timestamp: now,
              description: "Buyer confirmed receipt of item. Order completed successfully.",
              actor: "buyer" as const,
            },
          ],
        };
      })
    );
  }, []);

  const cancelOrder = useCallback((orderId: string, reason: string) => {
    const now = new Date().toISOString();
    setOrders((prev) =>
      prev.map((o) => {
        if (o.id !== orderId) return o;
        return {
          ...o,
          status: "cancelled" as const,
          cancelReason: reason,
          updatedAt: now,
          timeline: [
            ...o.timeline,
            {
              status: "cancelled" as const,
              timestamp: now,
              description: `Order cancelled. Reason: ${reason}`,
              actor: "seller" as const,
            },
          ],
        };
      })
    );
  }, []);

  const getOrderById = useCallback(
    (id: string) => orders.find((o) => o.id === id),
    [orders]
  );

  const buyerOrders = useMemo(
    () => orders.filter((o) => o.buyerId === "me"),
    [orders]
  );

  const sellerOrders = useMemo(
    () => orders.filter((o) => o.sellerId === "me"),
    [orders]
  );

  const value = useMemo(
    () => ({
      orders,
      updateOrderStatus,
      addTrackingInfo,
      raiseDispute,
      markReceived,
      cancelOrder,
      getOrderById,
      buyerOrders,
      sellerOrders,
    }),
    [
      orders,
      updateOrderStatus,
      addTrackingInfo,
      raiseDispute,
      markReceived,
      cancelOrder,
      getOrderById,
      buyerOrders,
      sellerOrders,
    ]
  );

  return <OrderContext.Provider value={value}>{children}</OrderContext.Provider>;
}

export const useOrders = () => useContext(OrderContext);
