import apiClient from "@/lib/axiosClient";
import { API_ENDPOINTS } from "@/lib/apiEndpoints";

/* ─── Status codes (backend contract) ────────────────────────────────────────
 * status:          0 Placed · 1 Confirmed · 2 Shipped · 3 Delivered · 4 Cancelled
 * payment_status:  0 Pending · 1 Paid · 2 Failed
 */
export type OrderStatusCode = 0 | 1 | 2 | 3 | 4;
export type PaymentStatusCode = 0 | 1 | 2;

export const ORDER_STATUS = {
  PLACED: 0,
  CONFIRMED: 1,
  SHIPPED: 2,
  DELIVERED: 3,
  CANCELLED: 4,
} as const;

export const ORDER_STATUS_META: Record<
  number,
  { label: string; color: string }
> = {
  0: { label: "Placed", color: "#6366f1" },
  1: { label: "Confirmed", color: "#3b82f6" },
  2: { label: "Shipped", color: "#f59e0b" },
  3: { label: "Delivered", color: "#22c55e" },
  4: { label: "Cancelled", color: "#ef4444" },
};

export const PAYMENT_STATUS_META: Record<
  number,
  { label: string; color: string }
> = {
  0: { label: "Payment Pending", color: "#f59e0b" },
  1: { label: "Paid", color: "#22c55e" },
  2: { label: "Payment Failed", color: "#ef4444" },
};

export function orderStatusMeta(status: number) {
  return ORDER_STATUS_META[status] ?? { label: "Unknown", color: "#6b7280" };
}

export function paymentStatusMeta(status: number) {
  return PAYMENT_STATUS_META[status] ?? { label: "Unknown", color: "#6b7280" };
}

/* ─── Raw API shapes ─────────────────────────────────────────────────────── */
interface ApiOrder {
  id: number;
  listing_id: number;
  buyer_id: number;
  seller_id: number;
  quantity: number;
  price: number;
  admin_commission: number;
  seller_earning: number;
  tracking_number: string;
  address: string;
  city: string;
  state: string;
  country: string;
  pincode: number | string;
  transaction_id: string;
  payment_status: number;
  status: number;
  created_at: string;
  updated_at: string;
  // present on list/detail endpoints
  listing_name?: string;
  listing_image?: string;
  seller_full_name?: string;
  seller_channel_name?: string;
  seller_firebase_id?: string;
  seller_image?: string;
  buyer_full_name?: string;
  buyer_channel_name?: string;
  buyer_firebase_id?: string;
  buyer_image?: string;
}

/* ─── App-facing model ───────────────────────────────────────────────────── */
export interface MarketplaceOrder {
  id: number;
  listingId: number;
  buyerId: number;
  sellerId: number;
  quantity: number;
  price: number;
  adminCommission: number;
  sellerEarning: number;
  trackingNumber: string;
  address: string;
  city: string;
  state: string;
  country: string;
  pincode: string;
  transactionId: string;
  paymentStatus: number;
  status: number;
  createdAt: string;
  updatedAt: string;
  listingName: string;
  listingImage: string;
  sellerName: string;
  sellerChannelName: string;
  sellerFirebaseId: string;
  sellerImage: string;
  buyerName: string;
  buyerChannelName: string;
  buyerFirebaseId: string;
  buyerImage: string;
}

export interface OrderCounts {
  total: number;
  confirmed: number;
  shipped: number;
  delivered: number;
  cancelled: number;
}

export interface OrdersPage {
  orders: MarketplaceOrder[];
  counts: OrderCounts;
  totalRows: number;
  totalPage: number;
  currentPage: number;
  hasMore: boolean;
}

export interface OrderReview {
  id: number;
  classifiedOrderId: number;
  sellerId: number;
  userId: number;
  review: string;
  rating: number;
  createdAt: string;
}

function mapOrder(o: ApiOrder): MarketplaceOrder {
  return {
    id: o.id,
    listingId: o.listing_id,
    buyerId: o.buyer_id,
    sellerId: o.seller_id,
    quantity: o.quantity ?? 1,
    price: o.price ?? 0,
    adminCommission: o.admin_commission ?? 0,
    sellerEarning: o.seller_earning ?? 0,
    trackingNumber: o.tracking_number ?? "",
    address: o.address ?? "",
    city: o.city ?? "",
    state: o.state ?? "",
    country: o.country ?? "",
    pincode: String(o.pincode ?? ""),
    transactionId: o.transaction_id ?? "",
    paymentStatus: o.payment_status ?? 0,
    status: o.status ?? 0,
    createdAt: o.created_at ?? "",
    updatedAt: o.updated_at ?? "",
    listingName: o.listing_name ?? "",
    listingImage: o.listing_image ?? "",
    sellerName: o.seller_full_name ?? "",
    sellerChannelName: o.seller_channel_name ?? "",
    sellerFirebaseId: o.seller_firebase_id ?? "",
    sellerImage: o.seller_image ?? "",
    buyerName: o.buyer_full_name ?? "",
    buyerChannelName: o.buyer_channel_name ?? "",
    buyerFirebaseId: o.buyer_firebase_id ?? "",
    buyerImage: o.buyer_image ?? "",
  };
}

/* eslint-disable @typescript-eslint/no-explicit-any */
function mapCounts(data: any): OrderCounts {
  return {
    total: data?.total_order ?? 0,
    confirmed: data?.total_confirm_order ?? 0,
    shipped: data?.total_shipped_order ?? 0,
    delivered: data?.total_delivered_order ?? 0,
    cancelled: data?.total_cancelled_order ?? 0,
  };
}

function mapOrdersPage(data: any): OrdersPage {
  const rows: ApiOrder[] = Array.isArray(data?.result) ? data.result : [];
  return {
    orders: rows.map(mapOrder),
    counts: mapCounts(data),
    totalRows: data?.total_rows ?? rows.length,
    totalPage: data?.total_page ?? 1,
    currentPage: data?.current_page ?? 1,
    hasMore: data?.more_page ?? false,
  };
}
/* eslint-enable @typescript-eslint/no-explicit-any */

/* ─── Test mode ──────────────────────────────────────────────────────────── */
/** Payment-gateway bypass for testing: enabled in dev builds, or anywhere
 *  via NEXT_PUBLIC_BYPASS_PAYMENT=true. Never enable in production. */
export const isPaymentBypassEnabled = () =>
  process.env.NODE_ENV === "development" ||
  process.env.NEXT_PUBLIC_BYPASS_PAYMENT === "true";

export const makeTestTransactionId = (orderId: number) =>
  `TEST-${orderId}-${Date.now()}`;

/* ─── Service ────────────────────────────────────────────────────────────── */
/* Note: user_id is auto-injected into every POST body by the axios
 * request interceptor — never pass it manually. */
export const orderService = {
  /** Creates the order (status 0 / payment pending). Returns the created order. */
  initiateOrder: async (params: {
    listingId: number | string;
    quantity: number;
    address: string;
    city: string;
    state: string;
    country: string;
    pincode: string;
  }): Promise<MarketplaceOrder> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.INITIATE, {
      listing_id: params.listingId,
      quantity: params.quantity,
      address: params.address,
      city: params.city,
      state: params.state,
      country: params.country,
      pincode: params.pincode,
    });
    const order = res.data?.result?.[0];
    if (!order) throw new Error("Order could not be created.");
    return mapOrder(order);
  },

  /** payment_status: 1 = Paid, 2 = Failed. transaction_id optional (PayPal capture ID). */
  confirmOrderPayment: async (
    orderId: number,
    paymentStatus: 1 | 2,
    transactionId?: string,
  ): Promise<void> => {
    await apiClient.post(API_ENDPOINTS.ORDER.CONFIRM_PAYMENT, {
      order_id: orderId,
      payment_status: paymentStatus,
      ...(transactionId ? { transaction_id: transactionId } : {}),
    });
  },

  /** Buyer's orders. status: "all" or 0–4. search matches listing title & order price. */
  getMyOrders: async (params?: {
    status?: OrderStatusCode | "all";
    search?: string;
    page?: number;
  }): Promise<OrdersPage> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.GET_MY_ORDERS, {
      status: params?.status ?? "all",
      ...(params?.search ? { search: params.search } : {}),
      ...(params?.page ? { page: params.page } : {}),
    });
    return mapOrdersPage(res.data);
  },

  getOrderDetail: async (orderId: number | string): Promise<MarketplaceOrder> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.GET_DETAIL, {
      order_id: orderId,
    });
    const order = res.data?.result?.[0];
    if (!order) throw new Error("Order not found.");
    return mapOrder(order);
  },

  /** Seller's received orders. status: "all" or 0–4. */
  getMySales: async (params?: {
    status?: OrderStatusCode | "all";
    page?: number;
  }): Promise<OrdersPage> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.GET_MY_SALES, {
      status: params?.status ?? "all",
      ...(params?.page ? { page: params.page } : {}),
    });
    return mapOrdersPage(res.data);
  },

  /** Seller updates fulfilment: 2 = Shipped (tracking optional), 3 = Delivered. */
  updateOrderStatus: async (
    orderId: number,
    status: 2 | 3,
    trackingNumber?: string,
  ): Promise<void> => {
    await apiClient.post(API_ENDPOINTS.ORDER.UPDATE_STATUS, {
      order_id: orderId,
      status,
      ...(trackingNumber ? { tracking_number: trackingNumber } : {}),
    });
  },

  /** Buyer reviews a delivered order. rating 1–5. */
  addOrderReview: async (params: {
    orderId: number;
    sellerId: number;
    review: string;
    rating: number;
  }): Promise<void> => {
    await apiClient.post(API_ENDPOINTS.ORDER.ADD_REVIEW, {
      classified_order_id: params.orderId,
      seller_id: params.sellerId,
      review: params.review,
      rating: params.rating,
    });
  },

  /** Reviews written by the current user. */
  getMyReviews: async (): Promise<OrderReview[]> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.GET_REVIEW, {});
    const rows = Array.isArray(res.data?.result) ? res.data.result : [];
    /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
    return rows.map((r: any) => ({
      id: r.id ?? 0,
      classifiedOrderId: r.classified_order_id ?? 0,
      sellerId: r.seller_id ?? 0,
      userId: r.user_id ?? 0,
      review: r.review ?? "",
      rating: Number(r.rating ?? 0),
      createdAt: r.created_at ?? "",
    }));
  },

  /** Returns the invoice PDF URL from result[0].invoice_pdf. */
  getInvoicePdfUrl: async (orderId: number): Promise<string> => {
    const res = await apiClient.post(API_ENDPOINTS.ORDER.GET_INVOICE_PDF, {
      order_id: orderId,
    });
    const url = res.data?.result?.[0]?.invoice_pdf;
    if (typeof url !== "string" || !url) {
      throw new Error("Invoice not available.");
    }
    return url;
  },
};
