import apiClient from "./apiClient";

export type ClientStatus = "active" | "inactive";
export type ClientType = "private" | "pkce";

export type ClientSummary = {
  id: string;
  name: string;
  type: ClientType;
  status: ClientStatus;
  createdAt?: string;
  clientSecret?: string;
  tokenEndpointAuthMethod?: string;
  jwksUri?: string;
  redirectUris: string[];
  scopes: string[];
  metadata?: Record<string, unknown>;
};

export type ClientListResponse = {
  items: ClientSummary[];
  limit: number;
  offset: number;
};

export type DevStats = {
  total_clients: number;
  active_sessions: number;
  auth_failures_24h: number;
};

export type DevAuditLog = {
  event_id: string;
  timestamp: string;
  user_id: string;
  event_type: string;
  status: string;
  ip_address: string;
  user_agent: string;
  device_id?: string;
  details?: string;
};

export type DevAuditLogListResponse = {
  items: DevAuditLog[];
  limit: number;
  cursor?: string;
  next_cursor?: string;
};

export type ClientEndpoints = {
  discovery: string;
  issuer: string;
  authorization: string;
  token: string;
  userinfo: string;
};

export type ClientDetailResponse = {
  client: ClientSummary & {
    clientSecret?: string;
    metadata?: Record<string, unknown>;
  };
  endpoints: ClientEndpoints;
  headlessJwksCache?: {
    clientId: string;
    jwksUri: string;
    cachedAt: string;
    expiresAt: string;
    lastCheckedAt?: string;
    lastSuccessfulVerificationAt?: string;
    lastRefreshStatus?: "success" | "failure" | "pending";
    lastError?: string;
    consecutiveFailures?: number;
    cachedKids?: string[];
    etag?: string;
    lastModified?: string;
    parsedKeys?: Array<{
      kid?: string;
      kty?: string;
      use?: string;
      alg?: string;
      n?: string;
    }>;
  };
};

export type ClientUpsertRequest = {
  id?: string;
  name?: string;
  type?: ClientType;
  status?: ClientStatus;
  redirectUris?: string[];
  scopes?: string[];
  grantTypes?: string[];
  responseTypes?: string[];
  tokenEndpointAuthMethod?: string;
  jwksUri?: string;
  metadata?: Record<string, unknown>;
};

export type ConsentSummary = {
  subject: string;
  userName?: string;
  clientId: string;
  clientName?: string;
  grantedScopes: string[];
  authenticatedAt?: string;
  createdAt: string;
  deletedAt?: string;
  status: "active" | "revoked";
  tenantId?: string;
  tenantName?: string;
};

export type ConsentListResponse = {
  items: ConsentSummary[];
};

// --- Federation / IdP Config Types ---
export type ProviderType = "oidc" | "saml";

export type IdpConfig = {
  id: string;
  client_id: string; // Changed from tenant_id
  provider_type: ProviderType;
  display_name: string;
  status: "active" | "inactive";
  issuer_url?: string;
  // OIDC specific fields
  oidc_client_id?: string;
  oidc_client_secret?: string;
  scopes?: string;
  // SAML specific fields
  metadata_url?: string;
  metadata_xml?: string;
  entity_id?: string;
  acs_url?: string;
  createdAt: string;
  updatedAt: string;
};

export type IdpConfigCreateRequest = Omit<
  IdpConfig,
  "id" | "createdAt" | "updatedAt"
>;
export type IdpConfigUpdateRequest = Partial<IdpConfigCreateRequest>;
// --- End Federation Types ---

export async function fetchClients() {
  const { data } = await apiClient.get<ClientListResponse>("/dev/clients");
  return data;
}

export async function fetchDevStats() {
  const { data } = await apiClient.get<DevStats>("/dev/stats");
  return data;
}

export async function fetchClient(clientId: string) {
  const { data } = await apiClient.get<ClientDetailResponse>(
    `/dev/clients/${clientId}`,
  );
  return data;
}

export async function updateClientStatus(
  clientId: string,
  status: ClientStatus,
) {
  const { data } = await apiClient.patch<ClientDetailResponse>(
    `/dev/clients/${clientId}/status`,
    { status },
  );
  return data;
}

export async function createClient(payload: ClientUpsertRequest) {
  const { data } = await apiClient.post<ClientDetailResponse>(
    "/dev/clients",
    payload,
  );
  return data;
}

export async function updateClient(
  clientId: string,
  payload: ClientUpsertRequest,
) {
  const { data } = await apiClient.put<ClientDetailResponse>(
    `/dev/clients/${clientId}`,
    payload,
  );
  return data;
}

export async function rotateClientSecret(clientId: string) {
  const { data } = await apiClient.post<ClientDetailResponse>(
    `/dev/clients/${clientId}/secret/rotate`,
  );
  return data;
}

export async function refreshHeadlessJwksCache(clientId: string) {
  const { data } = await apiClient.post<ClientDetailResponse>(
    `/dev/clients/${clientId}/headless-jwks/refresh`,
  );
  return data;
}

export async function revokeHeadlessJwksCache(clientId: string) {
  await apiClient.delete(`/dev/clients/${clientId}/headless-jwks/cache`);
}

export async function deleteClient(clientId: string) {
  await apiClient.delete(`/dev/clients/${clientId}`);
}

export async function fetchConsents(
  subject: string,
  clientId?: string,
  status?: string,
) {
  const params: Record<string, string> = { subject };
  if (clientId) {
    params.client_id = clientId;
  }
  if (status && status !== "all") {
    params.status = status;
  }
  const { data } = await apiClient.get<ConsentListResponse>("/dev/consents", {
    params,
  });
  return data;
}

export async function revokeConsent(subject: string, clientId?: string) {
  const params: Record<string, string> = { subject };
  if (clientId) {
    params.client_id = clientId;
  }
  await apiClient.delete("/dev/consents", { params });
}

// --- Federation / IdP Config API Calls ---

export async function listIdpConfigsForClient(clientId: string) {
  const { data } = await apiClient.get<IdpConfig[]>(
    `/dev/clients/${clientId}/idps`,
  );
  return data;
}

export async function createIdpConfigForClient(
  payload: IdpConfigCreateRequest,
) {
  const { data } = await apiClient.post<IdpConfig>(
    `/dev/clients/${payload.client_id}/idps`,
    payload,
  );
  return data;
}

export async function updateIdpConfig(
  clientId: string,
  idpId: string,
  payload: IdpConfigUpdateRequest,
) {
  const { data } = await apiClient.put<IdpConfig>(
    `/dev/clients/${clientId}/idps/${idpId}`,
    payload,
  );
  return data;
}

export async function deleteIdpConfig(clientId: string, idpId: string) {
  await apiClient.delete(`/dev/clients/${clientId}/idps/${idpId}`);
}

export async function fetchDevAuditLogs(
  limit = 50,
  cursor?: string,
  filters?: {
    action?: string;
    client_id?: string;
    status?: string;
    tenant_id?: string;
  },
) {
  const { data } = await apiClient.get<DevAuditLogListResponse>(
    "/dev/audit-logs",
    {
      params: {
        limit,
        cursor,
        action: filters?.action,
        client_id: filters?.client_id,
        status: filters?.status,
        tenant_id: filters?.tenant_id,
      },
    },
  );
  return data;
}

export type TenantSummary = {
  id: string;
  name: string;
  slug: string;
};

export async function fetchMyTenants() {
  const { data } = await apiClient.get<TenantSummary[]>("/dev/my-tenants");
  return data;
}
