import { serverRequest } from "./serverConnection";

export interface BetaApplicationInput {
  name: string;
  email: string;
  phone: string;
  wechat: string;
  industry: string;
  company: string;
  city: string;
  aiTools: string;
  aiDuration: string;
  aiTrack: string;
  aiDirection: string[];
  weeklyUsage: string;
  feedbackWilling: string;
  wantFeature: string[];
  selfStatement: string;
  signature: string;
  applicationDate: string;
  agreeRules: boolean;
}

export type BetaApplicationStatus = "pending" | "approved" | "rejected";

export interface BetaApplicationItem extends BetaApplicationInput {
  id: number;
  userId: number | null;
  username: string | null;
  status: BetaApplicationStatus;
  inviteCode: string | null;
  reviewNote: string | null;
  reviewedBy: number | null;
  reviewerUsername: string | null;
  reviewedAt: string | null;
  ipAddress: string | null;
  userAgent: string | null;
  createdAt: string;
  updatedAt: string;
}

export interface BetaApplicationSubmitResult {
  id: number;
  status: BetaApplicationStatus;
  createdAt: string;
}

function readString(value: unknown): string {
  return typeof value === "string" ? value : "";
}

function readNullableString(value: unknown): string | null {
  return typeof value === "string" && value ? value : null;
}

function readNumberOrNull(value: unknown): number | null {
  if (value === null || value === undefined || value === "") return null;
  const next = Number(value);
  return Number.isFinite(next) ? next : null;
}

function readStringArray(value: unknown): string[] {
  return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
}

function normalizeStatus(value: unknown): BetaApplicationStatus {
  return value === "approved" || value === "rejected" ? value : "pending";
}

function normalizeApplication(raw: unknown): BetaApplicationItem {
  const item = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>) : {};
  return {
    id: Number(item.id) || 0,
    userId: readNumberOrNull(item.userId),
    username: readNullableString(item.username),
    name: readString(item.name),
    email: readString(item.email),
    phone: readString(item.phone),
    wechat: readString(item.wechat),
    industry: readString(item.industry),
    company: readString(item.company),
    city: readString(item.city),
    aiTools: readString(item.aiTools),
    aiDuration: readString(item.aiDuration),
    aiTrack: readString(item.aiTrack),
    aiDirection: readStringArray(item.aiDirection),
    weeklyUsage: readString(item.weeklyUsage),
    feedbackWilling: readString(item.feedbackWilling),
    wantFeature: readStringArray(item.wantFeature),
    selfStatement: readString(item.selfStatement),
    signature: readString(item.signature),
    applicationDate: readString(item.applicationDate),
    agreeRules: item.agreeRules === true,
    status: normalizeStatus(item.status),
    inviteCode: readNullableString(item.inviteCode),
    reviewNote: readNullableString(item.reviewNote),
    reviewedBy: readNumberOrNull(item.reviewedBy),
    reviewerUsername: readNullableString(item.reviewerUsername),
    reviewedAt: readNullableString(item.reviewedAt),
    ipAddress: readNullableString(item.ipAddress),
    userAgent: readNullableString(item.userAgent),
    createdAt: readString(item.createdAt),
    updatedAt: readString(item.updatedAt),
  };
}

export const betaApplicationClient = {
  async submit(input: BetaApplicationInput): Promise<BetaApplicationSubmitResult> {
    const payload = await serverRequest<{ application: BetaApplicationSubmitResult }>("beta-applications", {
      method: "POST",
      body: input,
      maxRetries: 0,
      fallbackMessage: "提交内测申请失败",
    });
    return payload.application;
  },

  async listAdminApplications(status?: BetaApplicationStatus | ""): Promise<BetaApplicationItem[]> {
    const query = status ? `?status=${encodeURIComponent(status)}` : "";
    const payload = await serverRequest<{ applications?: unknown[] }>(`admin/beta-applications${query}`, {
      fallbackMessage: "读取内测申请失败",
    });
    return Array.isArray(payload.applications) ? payload.applications.map(normalizeApplication) : [];
  },

  async reviewApplication(
    id: number,
    action: "approve" | "reject",
    reviewNote?: string,
  ): Promise<BetaApplicationItem> {
    const payload = await serverRequest<{ application: unknown }>(`admin/beta-applications/${id}`, {
      method: "PATCH",
      body: { action, reviewNote },
      maxRetries: 0,
      fallbackMessage: "审核内测申请失败",
    });
    return normalizeApplication(payload.application);
  },
};
