import { Injectable, Logger, ServiceUnavailableException } from '@nestjs/common';

export interface JinshujuEntry {
  serial_number: number;
  /** field values — keyed by api_code like field_1, field_2 */
  [fieldKey: string]: unknown;
  created_at: string;
  updated_at: string;
}

export interface JinshujuEntriesResponse {
  total: number;
  count: number;
  data: JinshujuEntry[];
  next: number | null;
}

export interface JinshujuFormField {
  key: string;
  label: string;
  type: string;
}

interface JinshujuFormResponse {
  name: string;
  fields: Array<Record<string, { label?: unknown; type?: unknown }>>;
}

@Injectable()
export class JinshujuService {
  private readonly logger = new Logger(JinshujuService.name);
  private static readonly BASE = 'https://jinshuju.net/api/v1';

  private getAuthorization(apiKey: string, apiSecret: string): string {
    return `Basic ${Buffer.from(`${apiKey}:${apiSecret}`).toString('base64')}`;
  }

  async fetchFormFields(
    apiKey: string,
    apiSecret: string,
    formToken: string,
  ): Promise<{ name: string; fields: JinshujuFormField[] }> {
    const response = await fetch(
      `${JinshujuService.BASE}/forms/${encodeURIComponent(formToken)}`,
      {
        headers: {
          Authorization: this.getAuthorization(apiKey, apiSecret),
          Accept: 'application/json',
        },
      },
    );
    if (!response.ok) {
      const text = await response.text().catch(() => '');
      throw new ServiceUnavailableException(
        `获取金数据表单结构失败: HTTP ${response.status} ${text.slice(0, 200)}`,
      );
    }

    const body = (await response.json()) as JinshujuFormResponse;
    const fields = (body.fields ?? []).flatMap((group) =>
      Object.entries(group).map(([key, field]) => ({
        key,
        label: typeof field.label === 'string' && field.label.trim() ? field.label.trim() : key,
        type: typeof field.type === 'string' ? field.type : 'unknown',
      })),
    );
    return { name: body.name, fields };
  }

  /** Fetch all entries for a form, following pagination. */
  async fetchAllEntries(apiKey: string, apiSecret: string, formToken: string): Promise<JinshujuEntry[]> {
    const auth = this.getAuthorization(apiKey, apiSecret);
    const entries: JinshujuEntry[] = [];
    let next: number | null | undefined = undefined;

    do {
      const url = new URL(`${JinshujuService.BASE}/forms/${encodeURIComponent(formToken)}/entries`);
      if (next) url.searchParams.set('next', String(next));

      this.logger.log(`Fetching Jinshuju entries: ${url.toString().replace(/api_key=[^&]+/, 'api_key=***')}`);
      const res = await fetch(url.toString(), {
        headers: {
          Authorization: auth,
          Accept: 'application/json',
        },
      });

      if (!res.ok) {
        const text = await res.text().catch(() => '');
        throw new ServiceUnavailableException(`金数据 API 请求失败: HTTP ${res.status} ${text.slice(0, 200)}`);
      }

      const body = (await res.json()) as JinshujuEntriesResponse;
      entries.push(...body.data);
      next = body.next ?? undefined;
    } while (next);

    this.logger.log(`Fetched ${entries.length} entries from Jinshuju form ${formToken}`);
    return entries;
  }
}
