import axios from '@/network/axios';
import { apis } from '@/utils/apis/apis';
import { SuccessResponse } from '@/utils/types/Responses';
import {
  Category,
  CategoryListData,
  CreateCategoryPayload,
  MarkPaidPayload,
  Offer,
  OfferListData,
  RejectOfferPayload,
  RejectWithdrawalPayload,
  UpdateCategoryPayload,
  Withdrawal,
  WithdrawalListData,
} from './type';

const M = apis.DASHBOARD.MARKETPLACE_ADMIN;

// ─── Withdrawals ────────────────────────────────────────────────────────────

export const fetchWithdrawals = async (
  params?: Record<string, unknown>,
): Promise<WithdrawalListData> => {
  const response = await axios.get<SuccessResponse<WithdrawalListData>>(
    M.WITHDRAWALS.LIST,
    { params },
  );
  return response.data?.data;
};

export const fetchWithdrawal = async (id: number): Promise<Withdrawal> => {
  const response = await axios.get<SuccessResponse<Withdrawal>>(
    M.WITHDRAWALS.SHOW(id),
  );
  return response.data?.data;
};

export const approveWithdrawal = async (id: number): Promise<Withdrawal> => {
  const response = await axios.post<SuccessResponse<Withdrawal>>(
    M.WITHDRAWALS.APPROVE(id),
  );
  return response.data?.data;
};

export const rejectWithdrawal = async (
  id: number,
  payload: RejectWithdrawalPayload,
): Promise<Withdrawal> => {
  const response = await axios.post<SuccessResponse<Withdrawal>>(
    M.WITHDRAWALS.REJECT(id),
    payload,
  );
  return response.data?.data;
};

export const markWithdrawalPaid = async (
  id: number,
  payload: MarkPaidPayload,
): Promise<Withdrawal> => {
  const response = await axios.post<SuccessResponse<Withdrawal>>(
    M.WITHDRAWALS.MARK_PAID(id),
    payload,
  );
  return response.data?.data;
};

// ─── Offers ─────────────────────────────────────────────────────────────────

type LaravelPaginator<T> = {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
  data: T[];
};

type OffersRawResponse =
  | OfferListData
  | { offers: LaravelPaginator<Offer> | Offer[]; pagination?: PaginationBlock }
  | LaravelPaginator<Offer>
  | Offer[];

type PaginationBlock = {
  current_page?: number;
  last_page?: number;
  per_page?: number;
  total?: number;
};

const emptyList = (): OfferListData => ({
  items: [],
  meta: { current_page: 1, last_page: 1, per_page: 25, total: 0 },
});

const normalizeOfferList = (raw: OffersRawResponse | undefined): OfferListData => {
  if (!raw) return emptyList();

  // already normalized { items, meta }
  if (typeof raw === 'object' && !Array.isArray(raw) && 'items' in raw) {
    return raw as OfferListData;
  }

  // bare array
  if (Array.isArray(raw)) {
    return {
      items: raw,
      meta: { current_page: 1, last_page: 1, per_page: raw.length, total: raw.length },
    };
  }

  // { offers: ..., pagination?: ... }
  if (typeof raw === 'object' && 'offers' in raw) {
    const offers = (raw as { offers: LaravelPaginator<Offer> | Offer[] | null })
      .offers;
    const pagination = (raw as { pagination?: PaginationBlock }).pagination;

    if (offers == null) return emptyList();

    if (Array.isArray(offers)) {
      return {
        items: offers,
        meta: {
          current_page: pagination?.current_page ?? 1,
          last_page: pagination?.last_page ?? 1,
          per_page: pagination?.per_page ?? offers.length,
          total: pagination?.total ?? offers.length,
        },
      };
    }
    return {
      items: offers.data ?? [],
      meta: {
        current_page: offers.current_page,
        last_page: offers.last_page,
        per_page: offers.per_page,
        total: offers.total,
      },
    };
  }

  // bare paginator (must have a `data` array)
  if (
    typeof raw === 'object' &&
    raw !== null &&
    'data' in raw &&
    Array.isArray((raw as LaravelPaginator<Offer>).data)
  ) {
    const paginator = raw as LaravelPaginator<Offer>;
    return {
      items: paginator.data,
      meta: {
        current_page: paginator.current_page ?? 1,
        last_page: paginator.last_page ?? 1,
        per_page: paginator.per_page ?? paginator.data.length,
        total: paginator.total ?? paginator.data.length,
      },
    };
  }

  // unrecognized shape (e.g., `{total: 0}` with no list) → safe empty
  return emptyList();
};

export const fetchOffers = async (
  params?: Record<string, unknown>,
): Promise<OfferListData> => {
  const response = await axios.get<SuccessResponse<OffersRawResponse>>(
    M.OFFERS.LIST,
    { params },
  );
  return normalizeOfferList(response.data?.data);
};

export const rejectOffer = async (
  id: number,
  payload: RejectOfferPayload,
): Promise<Offer> => {
  const response = await axios.post<SuccessResponse<Offer>>(
    M.OFFERS.REJECT(id),
    payload,
  );
  return response.data?.data;
};

// ─── Categories ─────────────────────────────────────────────────────────────

export const fetchCategories = async (): Promise<Category[]> => {
  const response = await axios.get<SuccessResponse<CategoryListData | Category[]>>(
    M.CATEGORIES.LIST,
  );
  const data = response.data?.data;
  if (Array.isArray(data)) return data;
  return data?.items ?? [];
};

export const createCategory = async (
  payload: CreateCategoryPayload,
): Promise<Category> => {
  const response = await axios.post<SuccessResponse<Category>>(
    M.CATEGORIES.CREATE,
    payload,
  );
  return response.data?.data;
};

export const updateCategory = async (
  id: number,
  payload: UpdateCategoryPayload,
): Promise<Category> => {
  const response = await axios.put<SuccessResponse<Category>>(
    M.CATEGORIES.UPDATE(id),
    payload,
  );
  return response.data?.data;
};

export const deleteCategory = async (id: number): Promise<void> => {
  await axios.delete(M.CATEGORIES.DELETE(id));
};

// ─── Settings ───────────────────────────────────────────────────────────────

export const updateCommission = async (
  commission_percent: number,
): Promise<{ commission_percent: number }> => {
  const response = await axios.put<SuccessResponse<{ commission_percent: number }>>(
    M.SETTINGS.UPDATE_COMMISSION,
    { commission_percent },
  );
  return response.data?.data;
};
