import { callAuthEndpoint } from "./http";
import { safeStringify } from "./utils";

export type Organization = {
  id: string;
  name: string;
  slug: string;
  createdAt?: string;
};

export type Member = {
  id: string;
  organizationId: string;
  userId: string;
  role: string;
  createdAt?: string;
  user?: {
    id?: string;
    email?: string | null;
    name?: string | null;
  };
};

export type Invitation = {
  id: string;
  organizationId: string;
  email: string;
  role: string;
  status: string;
  inviterId?: string;
  expiresAt?: string;
  createdAt?: string;
};

export type EmailRow = {
  id: string;
  recipientEmail: string;
  subject: string;
  fromAddress: string;
  provider: string;
  createdAt: string;
  metadata?: unknown;
};

export function normalizeOrganization(input: unknown): Organization | null {
  if (!input || typeof input !== "object") return null;
  const record = input as Record<string, unknown>;
  const id = typeof record.id === "string" ? record.id : null;
  const name = typeof record.name === "string" ? record.name : null;
  const slug = typeof record.slug === "string" ? record.slug : null;

  if (!id || !name || !slug) return null;

  return {
    id,
    name,
    slug,
    createdAt:
      typeof record.createdAt === "string"
        ? record.createdAt
        : typeof record.created_at === "string"
          ? record.created_at
          : undefined,
  };
}

export function normalizeMember(input: unknown): Member | null {
  if (!input || typeof input !== "object") return null;
  const record = input as Record<string, unknown>;
  const id = typeof record.id === "string" ? record.id : null;
  const organizationId =
    typeof record.organizationId === "string"
      ? record.organizationId
      : typeof record.organization_id === "string"
        ? record.organization_id
        : null;
  const userId =
    typeof record.userId === "string"
      ? record.userId
      : typeof record.user_id === "string"
        ? record.user_id
        : null;
  const role = typeof record.role === "string" ? record.role : null;

  if (!id || !organizationId || !userId || !role) return null;

  const user =
    record.user && typeof record.user === "object"
      ? {
          id:
            typeof (record.user as Record<string, unknown>).id === "string"
              ? ((record.user as Record<string, unknown>).id as string)
              : undefined,
          email:
            typeof (record.user as Record<string, unknown>).email === "string"
              ? ((record.user as Record<string, unknown>).email as string)
              : null,
          name:
            typeof (record.user as Record<string, unknown>).name === "string"
              ? ((record.user as Record<string, unknown>).name as string)
              : null,
        }
      : undefined;

  return {
    id,
    organizationId,
    userId,
    role,
    createdAt:
      typeof record.createdAt === "string"
        ? record.createdAt
        : typeof record.created_at === "string"
          ? record.created_at
          : undefined,
    user,
  };
}

export function normalizeInvitation(input: unknown): Invitation | null {
  if (!input || typeof input !== "object") return null;
  const record = input as Record<string, unknown>;
  const id = typeof record.id === "string" ? record.id : null;
  const organizationId =
    typeof record.organizationId === "string"
      ? record.organizationId
      : typeof record.organization_id === "string"
        ? record.organization_id
        : null;
  const email = typeof record.email === "string" ? record.email : null;
  const role = typeof record.role === "string" ? record.role : null;
  const status =
    typeof record.status === "string"
      ? record.status
      : typeof record.status === "object"
        ? safeStringify(record.status)
        : "unknown";

  if (!id || !organizationId || !email || !role) return null;

  return {
    id,
    organizationId,
    email,
    role,
    status,
    inviterId:
      typeof record.inviterId === "string"
        ? record.inviterId
        : typeof record.inviter_id === "string"
          ? record.inviter_id
          : undefined,
    expiresAt:
      typeof record.expiresAt === "string"
        ? record.expiresAt
        : typeof record.expires_at === "string"
          ? record.expires_at
          : undefined,
    createdAt:
      typeof record.createdAt === "string"
        ? record.createdAt
        : typeof record.created_at === "string"
          ? record.created_at
          : undefined,
  };
}

export function normalizeEmailRow(input: unknown): EmailRow | null {
  if (!input || typeof input !== "object") return null;
  const record = input as Record<string, unknown>;
  const id = typeof record.id === "string" ? record.id : null;
  const recipientEmail =
    typeof record.recipientEmail === "string"
      ? record.recipientEmail
      : typeof record.recipient_email === "string"
        ? record.recipient_email
        : null;
  const subject = typeof record.subject === "string" ? record.subject : null;
  const fromAddress =
    typeof record.fromAddress === "string"
      ? record.fromAddress
      : typeof record.from_address === "string"
        ? record.from_address
        : null;
  const provider =
    typeof record.provider === "string" ? record.provider : "unknown";
  const createdAt =
    typeof record.createdAt === "string"
      ? record.createdAt
      : typeof record.created_at === "string"
        ? record.created_at
        : "-";

  if (!id || !recipientEmail || !subject || !fromAddress) return null;

  return {
    id,
    recipientEmail,
    subject,
    fromAddress,
    provider,
    createdAt,
    metadata: record.metadata,
  };
}

export function createOrganizationApi() {
  return {
    call: callAuthEndpoint,
    listOrganizations: () =>
      callAuthEndpoint<unknown[]>("/organization/list", { method: "GET" }),
    listUserInvitations: () =>
      callAuthEndpoint<unknown[]>("/organization/list-user-invitations", {
        method: "GET",
      }),
    listMembers: (organizationId: string) =>
      callAuthEndpoint(
        `/organization/list-members?organizationId=${encodeURIComponent(organizationId)}&limit=250&offset=0`,
        { method: "GET" },
      ),
    listInvitations: (organizationId: string) =>
      callAuthEndpoint(
        `/organization/list-invitations?organizationId=${encodeURIComponent(organizationId)}`,
        { method: "GET" },
      ),
    checkSlug: (slug: string) =>
      callAuthEndpoint(`/organization/check-slug?slug=${encodeURIComponent(slug)}`, {
        method: "GET",
      }),
    createOrganization: (payload: { name: string; slug: string }) =>
      callAuthEndpoint("/organization/create", {
        method: "POST",
        body: JSON.stringify(payload),
      }),
    setActiveOrganization: (organizationId: string) =>
      callAuthEndpoint("/organization/set-active", {
        method: "POST",
        body: JSON.stringify({ organizationId }),
      }),
    inviteMember: (payload: {
      organizationId: string;
      email: string;
      role: string;
      callbackURL?: string;
    }) =>
      callAuthEndpoint("/organization/invite-member", {
        method: "POST",
        body: JSON.stringify(payload),
      }),
    acceptInvitation: (invitationId: string) =>
      callAuthEndpoint("/organization/accept-invitation", {
        method: "POST",
        body: JSON.stringify({ invitationId }),
      }),
    rejectInvitation: (invitationId: string) =>
      callAuthEndpoint("/organization/reject-invitation", {
        method: "POST",
        body: JSON.stringify({ invitationId }),
      }),
    cancelInvitation: (invitationId: string) =>
      callAuthEndpoint("/organization/cancel-invitation", {
        method: "POST",
        body: JSON.stringify({ invitationId }),
      }),
    updateMemberRole: (payload: {
      memberId: string;
      role: string;
      organizationId: string;
    }) =>
      callAuthEndpoint("/organization/update-member-role", {
        method: "POST",
        body: JSON.stringify(payload),
      }),
    removeMember: (payload: { memberId: string; organizationId: string }) =>
      callAuthEndpoint("/organization/remove-member", {
        method: "POST",
        body: JSON.stringify(payload),
      }),
    listEmailRows: (endpoint: string) =>
      callAuthEndpoint<{ emails?: unknown[] }>(endpoint, { method: "GET" }),
  };
}
