import type {
  AddressInput,
  AlertRecord,
  ApiResponse,
  CreateQuoteResult,
  CreateHostCustomerResponse,
  HostCustomerRecord,
  LoginResponse,
  MarkupConfig,
  MetricsDashboard,
  MothershipAddressCandidate,
  MothershipCandidatesResult,
  PaginatedResult,
  QueueStats,
  QuoteQueryLogRecord,
  QuoteDetail,
  QuoteRequestBody,
  Priority1QuoteRequestBody,
  FlockQuoteRequestBody,
  RpaStatus,
} from "@/lib/frontend/types";
import { CANDIDATES_FETCH_TIMEOUT_MS } from "@/lib/frontend/constants";

async function parseJson<T>(response: Response): Promise<ApiResponse<T>> {
  const contentType = response.headers.get("content-type") ?? "";
  if (!contentType.includes("application/json")) {
    const hint =
      response.status === 404
        ? "询价结果接口不可用（GET /api/quotes/{id}），请重新部署并确认已包含动态路由"
        : response.ok
          ? "响应解析失败"
          : `服务异常 (HTTP ${response.status})`;
    return {
      code: "INTERNAL_ERROR",
      message: hint,
      data: null,
    };
  }
  try {
    return (await response.json()) as ApiResponse<T>;
  } catch {
    return {
      code: "INTERNAL_ERROR",
      message: "响应解析失败",
      data: null,
    };
  }
}

function hostHeaders(
  serviceToken: string | undefined,
  customerId: string,
): Record<string, string> {
  const headers: Record<string, string> = {
    "X-Customer-Id": customerId,
    "Content-Type": "application/json",
    "Cache-Control": "no-store",
  };
  if (serviceToken?.trim()) {
    headers.Authorization = `Bearer ${serviceToken}`;
  }
  return headers;
}

function hostFetchInit(
  serviceToken: string | undefined,
  customerId: string,
  init: RequestInit,
): RequestInit {
  return {
    ...init,
    headers: hostHeaders(serviceToken, customerId),
    credentials: "include",
    cache: "no-store",
  };
}

function adminHeaders(token: string): Record<string, string> {
  return {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
    "Cache-Control": "no-store",
  };
}

export async function hostCreateQuote(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  body: QuoteRequestBody,
): Promise<ApiResponse<CreateQuoteResult>> {
  const response = await fetch(
    `${apiBaseUrl}/api/quotes`,
    hostFetchInit(serviceToken, body.customer_id, {
      method: "POST",
      body: JSON.stringify(body),
    }),
  );
  return parseJson(response);
}

export async function hostCreatePriority1Quote(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  body: Priority1QuoteRequestBody,
): Promise<ApiResponse<CreateQuoteResult>> {
  const response = await fetch(
    `${apiBaseUrl}/api/priority1/quotes`,
    hostFetchInit(serviceToken, body.customer_id, {
      method: "POST",
      body: JSON.stringify(body),
    }),
  );
  return parseJson(response);
}

export async function hostCreateFlockQuote(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  body: FlockQuoteRequestBody,
): Promise<ApiResponse<CreateQuoteResult>> {
  const response = await fetch(
    `${apiBaseUrl}/api/flock/quotes`,
    hostFetchInit(serviceToken, body.customer_id, {
      method: "POST",
      body: JSON.stringify(body),
    }),
  );
  return parseJson(response);
}

export async function hostFetchMothershipCandidates(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  pickup: Pick<AddressInput, "street" | "city" | "state" | "zip">,
  delivery: Pick<AddressInput, "street" | "city" | "state" | "zip">,
): Promise<ApiResponse<MothershipCandidatesResult>> {
  const controller = new AbortController();
  const timeout = setTimeout(
    () => controller.abort(),
    CANDIDATES_FETCH_TIMEOUT_MS,
  );

  try {
    const response = await fetch(
      `${apiBaseUrl}/api/addresses/mothership-candidates`,
      hostFetchInit(serviceToken, customerId, {
        method: "POST",
        body: JSON.stringify({
          customer_id: customerId,
          pickup_address: pickup,
          delivery_address: delivery,
        }),
        signal: controller.signal,
      }),
    );
    return parseJson(response);
  } catch (error) {
    if (error instanceof Error && error.name === "AbortError") {
      return {
        code: "QUOTE_TIMEOUT",
        message: "地址联想超时，MotherShip 响应较慢，请稍后重试",
        data: null,
      };
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }
}

export type MothershipSuggestResult = {
  candidates: MothershipAddressCandidate[];
};

/** 登录后一级：单边键入 MotherShip 地址联想 */
export async function hostSuggestMothershipAddress(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  query: string,
): Promise<ApiResponse<MothershipSuggestResult>> {
  const controller = new AbortController();
  const timeout = setTimeout(
    () => controller.abort(),
    CANDIDATES_FETCH_TIMEOUT_MS,
  );

  try {
    const response = await fetch(
      `${apiBaseUrl}/api/addresses/mothership-suggest`,
      hostFetchInit(serviceToken, customerId, {
        method: "POST",
        body: JSON.stringify({
          customer_id: customerId,
          query,
        }),
        signal: controller.signal,
      }),
    );
    return parseJson(response);
  } catch (error) {
    if (error instanceof Error && error.name === "AbortError") {
      return {
        code: "QUOTE_TIMEOUT",
        message: "地址联想超时，MotherShip 响应较慢，请稍后重试",
        data: null,
      };
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }
}

export async function hostPreheatQuoteSession(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  quoteSessionId: string,
): Promise<void> {
  try {
    await fetch(
      `${apiBaseUrl}/api/addresses/mothership-candidates/preheat`,
      hostFetchInit(serviceToken, customerId, {
        method: "POST",
        body: JSON.stringify({
          customer_id: customerId,
          quote_session_id: quoteSessionId,
        }),
      }),
    );
  } catch {
    /* 预热失败不阻断主流程 */
  }
}

export async function hostConfirmMothershipAddresses(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  quoteSessionId: string,
  pickup: MothershipCandidatesResult["pickup_candidates"][number],
  delivery: MothershipCandidatesResult["delivery_candidates"][number],
): Promise<ApiResponse<{ confirmed: boolean }>> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 300_000);
  try {
    const response = await fetch(
      `${apiBaseUrl}/api/addresses/mothership-candidates/confirm`,
      hostFetchInit(serviceToken, customerId, {
        method: "POST",
        body: JSON.stringify({
          customer_id: customerId,
          quote_session_id: quoteSessionId,
          pickup,
          delivery,
        }),
        signal: controller.signal,
      }),
    );
    return parseJson(response);
  } catch (error) {
    if (error instanceof Error && error.name === "AbortError") {
      return {
        code: "QUOTE_TIMEOUT",
        message: "地址确认超时，请重试",
        data: null,
      };
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }
}

export async function hostReleaseQuoteSession(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  quoteSessionId: string,
): Promise<void> {
  try {
    await fetch(
      `${apiBaseUrl}/api/addresses/mothership-candidates/release`,
      hostFetchInit(serviceToken, customerId, {
        method: "POST",
        body: JSON.stringify({
          customer_id: customerId,
          quote_session_id: quoteSessionId,
        }),
      }),
    );
  } catch {
    /* 释放失败不阻断 UI */
  }
}

export async function hostGetQuote(
  apiBaseUrl: string,
  serviceToken: string | undefined,
  customerId: string,
  quoteId: string,
): Promise<ApiResponse<QuoteDetail>> {
  const response = await fetch(
    `${apiBaseUrl}/api/quotes/${quoteId}`,
    hostFetchInit(serviceToken, customerId, {
      method: "GET",
    }),
  );
  return parseJson(response);
}

export type EmbedDemoLoginType = "password" | "api_key";

export type EmbedDemoSession = {
  customer_id: string;
  /** 登录类型：账号密码 / API Key（旧会话缺省为 password） */
  login_type?: EmbedDemoLoginType;
  markup: MarkupConfig;
  /** 客户是否已绑定承运商官网账密（驱动登录后查价 UI） */
  providers?: {
    mothership: { has_password: boolean };
    flock: { has_password: boolean };
  };
};

export async function embedDemoLogin(
  apiBaseUrl: string,
  customerId: string,
  password: string,
): Promise<ApiResponse<EmbedDemoSession>> {
  const response = await fetch(`${apiBaseUrl}/api/embed-demo/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({
      login_type: "password",
      customer_id: customerId,
      password,
    }),
    cache: "no-store",
  });
  return parseJson(response);
}

/** API Key 登录：只填 Key，服务端反查租户 */
export async function embedDemoLoginWithKey(
  apiBaseUrl: string,
  apiKey: string,
): Promise<ApiResponse<EmbedDemoSession>> {
  const response = await fetch(`${apiBaseUrl}/api/embed-demo/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({ login_type: "api_key", api_key: apiKey }),
    cache: "no-store",
  });
  return parseJson(response);
}

export type EmbedProviderCredential = {
  provider: "mothership" | "flock";
  email: string | null;
  /** 明文密码（embed 自助核对用；无配置时为 null） */
  password: string | null;
  has_password: boolean;
  updated_at: string | null;
};

/** 读取当前演示客户各承运商账密状态（邮箱 + 是否已配置） */
export async function embedGetProviderCredentials(
  apiBaseUrl: string,
): Promise<ApiResponse<{ customer_id: string; list: EmbedProviderCredential[] }>> {
  const response = await fetch(
    `${apiBaseUrl}/api/embed-demo/provider-credentials`,
    { credentials: "include", cache: "no-store" },
  );
  return parseJson(response);
}

/** 保存/修改当前演示客户承运商账密 */
export async function embedSaveProviderCredential(
  apiBaseUrl: string,
  provider: "mothership" | "flock",
  email: string,
  password: string,
): Promise<ApiResponse<EmbedProviderCredential>> {
  const response = await fetch(
    `${apiBaseUrl}/api/embed-demo/provider-credentials`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify({ provider, email, password }),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function embedDemoMe(
  apiBaseUrl: string,
): Promise<ApiResponse<EmbedDemoSession>> {
  const response = await fetch(`${apiBaseUrl}/api/embed-demo/me`, {
    credentials: "include",
    cache: "no-store",
  });
  return parseJson(response);
}

export async function embedDemoLogout(apiBaseUrl: string): Promise<void> {
  await fetch(`${apiBaseUrl}/api/embed-demo/logout`, {
    method: "POST",
    credentials: "include",
    cache: "no-store",
  });
}

export async function adminLogin(
  apiBaseUrl: string,
  username: string,
  password: string,
): Promise<ApiResponse<LoginResponse>> {
  const response = await fetch(`${apiBaseUrl}/api/auth/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ username, password }),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminGetAlerts(
  apiBaseUrl: string,
  token: string,
  page: number,
  size: number,
  type?: string,
  status?: string,
): Promise<ApiResponse<PaginatedResult<AlertRecord>>> {
  const params = new URLSearchParams({
    page: String(page),
    size: String(size),
  });
  if (type) params.set("type", type);
  if (status) params.set("status", status);

  const response = await fetch(`${apiBaseUrl}/api/alerts?${params}`, {
    headers: adminHeaders(token),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminResolveAlert(
  apiBaseUrl: string,
  token: string,
  alertId: string,
  resolverId: string,
): Promise<ApiResponse<AlertRecord>> {
  const response = await fetch(`${apiBaseUrl}/api/alerts/${alertId}/resolve`, {
    method: "POST",
    headers: adminHeaders(token),
    body: JSON.stringify({ resolver_id: resolverId }),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminGetCustomers(
  apiBaseUrl: string,
  token: string,
  page: number,
  size: number,
  keyword?: string,
): Promise<ApiResponse<PaginatedResult<HostCustomerRecord>>> {
  const params = new URLSearchParams({
    page: String(page),
    size: String(size),
  });
  if (keyword) params.set("keyword", keyword);

  const response = await fetch(
    `${apiBaseUrl}/api/admin/customers?${params}`,
    {
      headers: adminHeaders(token),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminCreateCustomer(
  apiBaseUrl: string,
  token: string,
  body: { name: string; remark?: string; embed_password?: string },
): Promise<ApiResponse<CreateHostCustomerResponse>> {
  const response = await fetch(`${apiBaseUrl}/api/admin/customers`, {
    method: "POST",
    headers: adminHeaders(token),
    body: JSON.stringify(body),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminUpdateCustomer(
  apiBaseUrl: string,
  token: string,
  customerId: string,
  body: {
    name?: string;
    status?: "active" | "disabled";
    remark?: string | null;
    embed_password?: string;
  },
): Promise<ApiResponse<HostCustomerRecord>> {
  const response = await fetch(
    `${apiBaseUrl}/api/admin/customers/${customerId}`,
    {
      method: "PATCH",
      headers: adminHeaders(token),
      body: JSON.stringify(body),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminRotateCustomerKey(
  apiBaseUrl: string,
  token: string,
  customerId: string,
): Promise<ApiResponse<CreateHostCustomerResponse>> {
  const response = await fetch(
    `${apiBaseUrl}/api/admin/customers/${customerId}/rotate-key`,
    {
      method: "POST",
      headers: adminHeaders(token),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export type ProviderCredentialProvider = "mothership" | "flock";

export type ProviderCredentialRecord = {
  provider: ProviderCredentialProvider;
  email: string | null;
  /** 管理端查看接口回传明文密码 */
  password?: string | null;
  has_password: boolean;
  updated_at: string | null;
};

export async function adminGetProviderCredentials(
  apiBaseUrl: string,
  token: string,
  customerId: string,
): Promise<
  ApiResponse<{ customer_id: string; list: ProviderCredentialRecord[] }>
> {
  const response = await fetch(
    `${apiBaseUrl}/api/admin/customers/${customerId}/provider-credentials`,
    {
      headers: adminHeaders(token),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminUpsertProviderCredential(
  apiBaseUrl: string,
  token: string,
  customerId: string,
  body: {
    provider: ProviderCredentialProvider;
    email?: string;
    password?: string;
    clear?: boolean;
  },
): Promise<ApiResponse<ProviderCredentialRecord>> {
  const response = await fetch(
    `${apiBaseUrl}/api/admin/customers/${customerId}/provider-credentials`,
    {
      method: "PUT",
      headers: adminHeaders(token),
      body: JSON.stringify(body),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminGetMarkupConfigs(
  apiBaseUrl: string,
  token: string,
  page: number,
  size: number,
  keyword?: string,
): Promise<ApiResponse<PaginatedResult<MarkupConfig>>> {
  const params = new URLSearchParams({
    page: String(page),
    size: String(size),
  });
  if (keyword) params.set("keyword", keyword);

  const response = await fetch(
    `${apiBaseUrl}/api/admin/markup-configs?${params}`,
    {
      headers: adminHeaders(token),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminUpdateMarkupConfig(
  apiBaseUrl: string,
  token: string,
  customerId: string,
  body: {
    markup_type: "percent" | "fixed";
    markup_percent?: number;
    markup_fixed_amount?: number;
    remark?: string;
  },
): Promise<ApiResponse<MarkupConfig>> {
  const response = await fetch(
    `${apiBaseUrl}/api/admin/markup-configs/${customerId}`,
    {
      method: "PUT",
      headers: adminHeaders(token),
      body: JSON.stringify(body),
      cache: "no-store",
    },
  );
  return parseJson(response);
}

export async function adminGetMetrics(
  apiBaseUrl: string,
  token: string,
): Promise<ApiResponse<MetricsDashboard>> {
  const response = await fetch(`${apiBaseUrl}/api/metrics/dashboard`, {
    headers: adminHeaders(token),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminGetRpaStatus(
  apiBaseUrl: string,
  token: string,
): Promise<ApiResponse<RpaStatus>> {
  const response = await fetch(`${apiBaseUrl}/api/rpa/status`, {
    headers: adminHeaders(token),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminGetQueryLogs(
  apiBaseUrl: string,
  token: string,
  page: number,
  size: number,
  customerId?: string,
  outcome?: string,
): Promise<ApiResponse<PaginatedResult<QuoteQueryLogRecord>>> {
  const params = new URLSearchParams({
    page: String(page),
    size: String(size),
  });
  if (customerId) params.set("customer_id", customerId);
  if (outcome) params.set("outcome", outcome);

  const response = await fetch(`${apiBaseUrl}/api/admin/query-logs?${params}`, {
    headers: adminHeaders(token),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminGetQueueStats(
  apiBaseUrl: string,
  token: string,
): Promise<ApiResponse<QueueStats>> {
  const response = await fetch(`${apiBaseUrl}/api/admin/queues/stats`, {
    headers: adminHeaders(token),
    cache: "no-store",
  });
  return parseJson(response);
}

export async function adminPauseWorker(
  apiBaseUrl: string,
  token: string,
  workerId: string,
  durationMinutes: number,
): Promise<ApiResponse<{ worker_id: string; message: string }>> {
  const response = await fetch(`${apiBaseUrl}/api/rpa/worker/pause`, {
    method: "POST",
    headers: adminHeaders(token),
    body: JSON.stringify({
      worker_id: workerId,
      duration_minutes: durationMinutes,
    }),
    cache: "no-store",
  });
  return parseJson(response);
}
