import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';

const POD_HEADERS = {
  'Content-Type': 'application/json;charset=UTF-8',
  Origin: 'https://inkpod.vip',
  Referer: 'https://inkpod.vip/',
} as const;

export interface SdsCategoryTreeNode {
  id: number | string | null;
  name?: string;
  icon?: string;
  children?: SdsCategoryTreeNode[];
  [key: string]: unknown;
}

export interface SdsProduct {
  id: number | string;
  name?: string;
  title?: string;
  pic?: string;
  image?: string;
  psd_img_url?: string;
  thumbImgUrl?: string;
  blankDesignUrl?: string;
  img_url?: string;
  show_img?: string;
  price?: number | string;
  currentPrice?: number | string;
  categoryId?: number | string;
  [key: string]: unknown;
}

export interface SdsProductsPage {
  items?: SdsProduct[];
  content?: SdsProduct[];
  totalCount?: number;
  totalElements?: number;
  total?: number;
  page?: number;
  size?: number;
  [key: string]: unknown;
}

/**
 * Thin wrapper around the SDS (mapi.sdspod.com) endpoints that the
 * `SyncService` consumes.
 *
 * Exposed as its own service so it can be mocked cleanly in unit tests.
 */
@Injectable()
export class SdsClientService {
  private readonly logger = new Logger(SdsClientService.name);
  private readonly baseUrl: string;

  constructor(
    private readonly http: HttpService,
    config: ConfigService,
  ) {
    this.baseUrl =
      config.get<string>('SDS_API_BASE')?.replace(/\/$/, '') ??
      'https://mapi.sdspod.com';
  }

  /**
   * Fetches the SDS category tree of type 3 (products category).
   * Body matches the legacy inkpod client.
   */
  async fetchCategoryTree(): Promise<SdsCategoryTreeNode[]> {
    const url = `${this.baseUrl}/category/tree/3`;
    const body = {
      withActivityArea: true,
      withPrivate: true,
      onlyHaveProduct: true,
    };
    const { data } = await firstValueFrom(
      this.http.post<SdsCategoryTreeNode[]>(url, body, { headers: POD_HEADERS }),
    );
    return Array.isArray(data) ? data : [];
  }

  /**
   * Fetches one page of products for a given SDS category.
   */
  async fetchProductsPage(
    categoryId: string | number,
    page = 1,
    size = 50,
  ): Promise<SdsProductsPage> {
    const url = `${this.baseUrl}/products/page`;
    const { data } = await firstValueFrom(
      this.http.get<SdsProductsPage>(url, {
        headers: POD_HEADERS,
        params: { categoryId, page, size },
      }),
    );
    return data ?? {};
  }
}
