/**
 * Credentials API Client
 * Handles credential-related API requests
 */

import { apiGet, apiPost, apiPatch, apiDelete, type ApiResponse } from "./client";

/**
 * Credential type enum (matches backend)
 */
export enum CredentialType {
  API_KEY = "API_KEY",
  OAUTH_TOKEN = "OAUTH_TOKEN",
  ACCESS_TOKEN = "ACCESS_TOKEN",
  SECRET = "SECRET",
  PASSWORD = "PASSWORD",
  CUSTOM = "CUSTOM",
}

/**
 * Credential scope enum (matches backend)
 */
export enum CredentialScope {
  USER = "USER",
  WORKSPACE = "WORKSPACE",
  SYSTEM = "SYSTEM",
}

/**
 * Credential response interface
 */
export interface Credential {
  id: string;
  userId: string;
  workspaceId: string | null;
  name: string;
  provider: string;
  type: CredentialType;
  scope: CredentialScope;
  maskedValue: string | null;
  description: string | null;
  expiresAt: Date | null;
  lastUsedAt: Date | null;
  metadata: Record<string, unknown>;
  isActive: boolean;
  rotatedAt: Date | null;
  createdAt: Date;
  updatedAt: Date;
}

/**
 * Create credential DTO
 */
export interface CreateCredentialDto {
  name: string;
  provider: string;
  type: CredentialType;
  scope?: CredentialScope;
  value: string;
  description?: string;
  expiresAt?: Date;
  metadata?: Record<string, unknown>;
}

/**
 * Update credential DTO
 */
export interface UpdateCredentialDto {
  name?: string;
  description?: string;
  expiresAt?: Date;
  metadata?: Record<string, unknown>;
}

/**
 * Query credential DTO
 */
export interface QueryCredentialDto {
  provider?: string;
  type?: CredentialType;
  scope?: CredentialScope;
  isActive?: boolean;
  page?: number;
  limit?: number;
}

/**
 * Credential value response
 */
export interface CredentialValueResponse {
  value: string;
}

/**
 * Fetch all credentials with optional filters
 * NEVER returns plaintext values - only maskedValue
 */
export async function fetchCredentials(
  workspaceId: string,
  query?: QueryCredentialDto
): Promise<ApiResponse<Credential[]>> {
  const params = new URLSearchParams();
  if (query?.provider) params.append("provider", query.provider);
  if (query?.type) params.append("type", query.type);
  if (query?.scope) params.append("scope", query.scope);
  if (query?.isActive !== undefined) params.append("isActive", String(query.isActive));
  if (query?.page) params.append("page", String(query.page));
  if (query?.limit) params.append("limit", String(query.limit));

  const endpoint = `/api/credentials${params.toString() ? `?${params.toString()}` : ""}`;
  return apiGet<ApiResponse<Credential[]>>(endpoint, workspaceId);
}

/**
 * Fetch a single credential by ID
 * NEVER returns plaintext value - only maskedValue
 */
export async function fetchCredential(id: string, workspaceId: string): Promise<Credential> {
  return apiGet<Credential>(`/api/credentials/${id}`, workspaceId);
}

/**
 * Decrypt and return credential value
 * CRITICAL: This is the ONLY endpoint that returns plaintext
 * Rate limited to 10 requests per minute per user
 */
export async function fetchCredentialValue(
  id: string,
  workspaceId: string
): Promise<CredentialValueResponse> {
  return apiGet<CredentialValueResponse>(`/api/credentials/${id}/value`, workspaceId);
}

/**
 * Create a new credential
 */
export async function createCredential(
  workspaceId: string,
  data: CreateCredentialDto
): Promise<Credential> {
  return apiPost<Credential>("/api/credentials", data, workspaceId);
}

/**
 * Update credential metadata (NOT the value itself)
 * Use rotateCredential to change the credential value
 */
export async function updateCredential(
  id: string,
  workspaceId: string,
  data: UpdateCredentialDto
): Promise<Credential> {
  return apiPatch<Credential>(`/api/credentials/${id}`, data, workspaceId);
}

/**
 * Replace credential value with new encrypted value
 */
export async function rotateCredential(
  id: string,
  workspaceId: string,
  newValue: string
): Promise<Credential> {
  return apiPost<Credential>(`/api/credentials/${id}/rotate`, { newValue }, workspaceId);
}

/**
 * Soft-delete credential (set isActive = false)
 */
export async function deleteCredential(
  id: string,
  workspaceId: string
): Promise<Record<string, never>> {
  return apiDelete<Record<string, never>>(`/api/credentials/${id}`, workspaceId);
}

/**
 * Audit log entry interface
 */
export interface AuditLogEntry {
  id: string;
  action: string;
  entityId: string;
  createdAt: string;
  details: Record<string, unknown>;
  user: {
    id: string;
    name: string | null;
    email: string;
  };
}

/**
 * Query parameters for audit log
 */
export interface QueryAuditLogDto {
  credentialId?: string;
  action?: string;
  startDate?: string;
  endDate?: string;
  page?: number;
  limit?: number;
}

/**
 * Fetch credential audit logs with optional filters
 * Shows all credential-related activities for the workspace
 */
export async function fetchCredentialAuditLog(
  workspaceId: string,
  query?: QueryAuditLogDto
): Promise<{
  data: AuditLogEntry[];
  meta: {
    total: number;
    page: number;
    limit: number;
    totalPages: number;
  };
}> {
  const params = new URLSearchParams();
  if (query?.credentialId) params.append("credentialId", query.credentialId);
  if (query?.action) params.append("action", query.action);
  if (query?.startDate) params.append("startDate", query.startDate);
  if (query?.endDate) params.append("endDate", query.endDate);
  if (query?.page) params.append("page", String(query.page));
  if (query?.limit) params.append("limit", String(query.limit));

  const endpoint = `/api/credentials/audit${params.toString() ? `?${params.toString()}` : ""}`;
  return apiGet(endpoint, workspaceId);
}

/**
 * Get provider icon name for lucide-react
 */
export function getProviderIcon(provider: string): string {
  const icons: Record<string, string> = {
    github: "Github",
    gitlab: "Gitlab",
    bitbucket: "Bitbucket",
    openai: "Brain",
    custom: "Key",
  };
  return icons[provider.toLowerCase()] ?? "Key";
}

/**
 * Format expiry status for PDA-friendly display
 */
export function getExpiryStatus(expiresAt: Date | null): {
  status: "active" | "approaching" | "past";
  label: string;
  className: string;
} {
  if (!expiresAt) {
    return { status: "active", label: "No expiry", className: "text-muted-foreground" };
  }

  const now = new Date();
  const expiry = new Date(expiresAt);
  const daysUntilExpiry = Math.floor((expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));

  if (daysUntilExpiry < 0) {
    return { status: "past", label: "Past target date", className: "text-orange-600" };
  } else if (daysUntilExpiry <= 7) {
    return { status: "approaching", label: "Approaching target", className: "text-yellow-600" };
  } else {
    return {
      status: "active",
      label: `Active (${String(daysUntilExpiry)}d)`,
      className: "text-green-600",
    };
  }
}
