import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { adminFetch } from './admin-api';

// ── Types ──────────────────────────────────────────────────────────────

export type OutboundMethod = 'POST' | 'PUT' | 'PATCH';
export type OutboundAuthKind = 'NONE' | 'BEARER' | 'BASIC';
export type TrustMode = 'SYSTEM_DEFAULT' | 'TRUST_ALL' | 'TRUST_PATHS';

// Jackson DEDUCTION mode picks subtype by which fields are present.
// None = {}, Bearer = { tokenCiphertext }, Basic = { username, passwordCiphertext }.
// Using a flat optional shape for pragmatic TypeScript compatibility.
export type OutboundAuth = {
  tokenCiphertext?: string;
  username?: string;
  passwordCiphertext?: string;
};

// Server returns this shape (`OutboundConnectionDto` in Java)
export interface OutboundConnectionDto {
  id: string;
  name: string;
  description: string | null;
  url: string;
  method: OutboundMethod;
  defaultHeaders: Record<string, string>;
  defaultBodyTmpl: string | null;
  tlsTrustMode: TrustMode;
  tlsCaPemPaths: string[];
  hmacSecretSet: boolean;
  authKind: OutboundAuthKind;
  allowedEnvironmentIds: string[];
  createdAt: string;
  createdBy: string;
  updatedAt: string;
  updatedBy: string;
}

// Client sends this shape for create/update (`OutboundConnectionRequest` in Java)
export interface OutboundConnectionRequest {
  name: string;
  description?: string | null;
  url: string;
  method: OutboundMethod;
  defaultHeaders?: Record<string, string>;
  defaultBodyTmpl?: string | null;
  tlsTrustMode: TrustMode;
  tlsCaPemPaths?: string[];
  hmacSecret?: string | null;
  auth: OutboundAuth;
  allowedEnvironmentIds?: string[];
}

// Server returns this from POST /{id}/test
export interface OutboundConnectionTestResult {
  status: number;
  latencyMs: number;
  responseSnippet: string | null;
  tlsProtocol: string | null;
  tlsCipherSuite: string | null;
  peerCertificateSubject: string | null;
  peerCertificateExpiresAtEpochMs: number | null;
  error: string | null;
}

// ── Query Hooks ────────────────────────────────────────────────────────

export function useOutboundConnections() {
  return useQuery({
    queryKey: ['admin', 'outbound-connections'],
    queryFn: () => adminFetch<OutboundConnectionDto[]>('/outbound-connections'),
  });
}

export function useOutboundConnection(id: string | undefined) {
  return useQuery({
    queryKey: ['admin', 'outbound-connections', id],
    queryFn: () => adminFetch<OutboundConnectionDto>(`/outbound-connections/${id}`),
    enabled: !!id,
  });
}

// ── Mutation Hooks ─────────────────────────────────────────────────────

export function useCreateOutboundConnection() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (req: OutboundConnectionRequest) =>
      adminFetch<OutboundConnectionDto>('/outbound-connections', {
        method: 'POST',
        body: JSON.stringify(req),
      }),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] }),
  });
}

export function useUpdateOutboundConnection(id: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (req: OutboundConnectionRequest) =>
      adminFetch<OutboundConnectionDto>(`/outbound-connections/${id}`, {
        method: 'PUT',
        body: JSON.stringify(req),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] });
      qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections', id] });
    },
  });
}

export function useDeleteOutboundConnection() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) =>
      adminFetch<void>(`/outbound-connections/${id}`, { method: 'DELETE' }),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] }),
  });
}

export function useTestOutboundConnection() {
  return useMutation({
    mutationFn: (id: string) =>
      adminFetch<OutboundConnectionTestResult>(`/outbound-connections/${id}/test`, {
        method: 'POST',
      }),
  });
}
