import { z } from 'zod'
import { type ContractJsonResponse, defineRouteContract } from '@/lib/api/contracts/types'
import {
  adminV1BooleanQuerySchema,
  adminV1IdParamsSchema,
  adminV1ListResponseSchema,
  adminV1PaginationQuerySchema,
  adminV1SingleResponseSchema,
  adminV1SubscriptionSchema,
} from '@/lib/api/contracts/v1/admin/shared'

export const adminV1OrganizationMemberParamsSchema = adminV1IdParamsSchema.extend({
  memberId: z.string().min(1),
})

export const adminV1OrganizationSchema = z.object({
  id: z.string(),
  name: z.string(),
  slug: z.string(),
  logo: z.string().nullable(),
  orgUsageLimit: z.string().nullable(),
  storageUsedBytes: z.number(),
  departedMemberUsage: z.string(),
  createdAt: z.string(),
  updatedAt: z.string(),
})

export const adminV1OrganizationDetailSchema = adminV1OrganizationSchema.extend({
  memberCount: z.number(),
  subscription: adminV1SubscriptionSchema.nullable(),
})

export const adminV1MemberSchema = z.object({
  id: z.string(),
  userId: z.string(),
  organizationId: z.string(),
  role: z.string(),
  createdAt: z.string(),
  userName: z.string(),
  userEmail: z.string(),
})

export const adminV1MemberDetailSchema = adminV1MemberSchema.extend({
  currentPeriodCost: z.string(),
  currentUsageLimit: z.string().nullable(),
  billingBlocked: z.boolean(),
})

export const adminV1OrganizationBillingSummarySchema = z.object({
  organizationId: z.string(),
  organizationName: z.string(),
  subscriptionPlan: z.string(),
  subscriptionStatus: z.string(),
  totalSeats: z.number(),
  usedSeats: z.number(),
  availableSeats: z.number(),
  totalCurrentUsage: z.number(),
  totalUsageLimit: z.number(),
  minimumBillingAmount: z.number(),
  averageUsagePerMember: z.number(),
  usagePercentage: z.number(),
  billingPeriodStart: z.string().nullable(),
  billingPeriodEnd: z.string().nullable(),
  membersOverLimit: z.number(),
  membersNearLimit: z.number(),
})

export const adminV1SeatAnalyticsSchema = z.object({
  organizationId: z.string(),
  organizationName: z.string(),
  currentSeats: z.number(),
  maxSeats: z.number(),
  availableSeats: z.number(),
  subscriptionPlan: z.string(),
  canAddSeats: z.boolean(),
  utilizationRate: z.number(),
})

export const adminV1CreateOrganizationBodySchema = z.object({
  name: z.string({ error: 'name is required' }).trim().min(1, { error: 'name is required' }),
  ownerId: z.string({ error: 'ownerId is required' }).min(1, { error: 'ownerId is required' }),
  slug: z.string().optional(),
})

export const adminV1UpdateOrganizationBodySchema = z.object({
  name: z
    .string({ error: 'name must be a non-empty string' })
    .trim()
    .min(1, { error: 'name must be a non-empty string' })
    .optional(),
  slug: z
    .string({ error: 'slug must be a non-empty string' })
    .trim()
    .min(1, { error: 'slug must be a non-empty string' })
    .optional(),
})

export const adminV1AddOrganizationMemberBodySchema = z.object({
  userId: z.string({ error: 'userId is required' }).min(1, { error: 'userId is required' }),
  role: z.enum(['admin', 'member'], { error: 'role must be "admin" or "member"' }),
})

export const adminV1UpdateOrganizationMemberBodySchema = z.object({
  role: z.enum(['admin', 'member'], { error: 'role must be "admin" or "member"' }),
})

export const adminV1RemoveOrganizationMemberQuerySchema = z.object({
  skipBillingLogic: adminV1BooleanQuerySchema,
})

export const adminV1UpdateOrganizationBillingBodySchema = z.object({
  orgUsageLimit: z
    .union([
      z
        .number({ error: 'orgUsageLimit must be a non-negative number or null' })
        .min(0, { error: 'orgUsageLimit must be a non-negative number or null' }),
      z.null(),
    ])
    .optional(),
})

export const adminV1TransferOwnershipBodySchema = z.object({
  newOwnerUserId: z
    .string({ error: 'newOwnerUserId is required' })
    .min(1, { error: 'newOwnerUserId is required' }),
  currentOwnerUserId: z
    .string({ error: 'currentOwnerUserId must be a non-empty string when provided' })
    .min(1, { error: 'currentOwnerUserId must be a non-empty string when provided' })
    .optional(),
})

const adminV1OrganizationMemberMutationResultSchema = adminV1MemberSchema.extend({
  action: z.enum(['created', 'updated', 'already_member']),
  billingActions: z.object({
    proUsageSnapshotted: z.boolean(),
    proCancelledAtPeriodEnd: z.boolean(),
  }),
})

const adminV1RemoveOrganizationMemberResultSchema = z.object({
  success: z.literal(true),
  memberId: z.string(),
  userId: z.string(),
  billingActions: z.object({
    usageCaptured: z.boolean(),
    proRestored: z.boolean(),
    usageRestored: z.boolean(),
    skipBillingLogic: z.boolean(),
  }),
})

const adminV1OrganizationBillingUpdateResultSchema = z.object({
  success: z.literal(true),
  orgUsageLimit: z.string().nullable(),
})

const adminV1TransferOwnershipResultSchema = z.object({
  organizationId: z.string(),
  currentOwnerUserId: z.string(),
  newOwnerUserId: z.string(),
  workspacesReassigned: z.number(),
  billedAccountReassigned: z.boolean(),
  overageMigrated: z.boolean(),
  billingBlockInherited: z.boolean(),
})

export const adminV1ListOrganizationsContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations',
  query: adminV1PaginationQuerySchema,
  response: {
    mode: 'json',
    schema: adminV1ListResponseSchema(adminV1OrganizationSchema),
  },
})

export const adminV1CreateOrganizationContract = defineRouteContract({
  method: 'POST',
  path: '/api/v1/admin/organizations',
  body: adminV1CreateOrganizationBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationSchema.extend({ memberId: z.string() })),
  },
})

export const adminV1GetOrganizationContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations/[id]',
  params: adminV1IdParamsSchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationDetailSchema),
  },
})

export const adminV1UpdateOrganizationContract = defineRouteContract({
  method: 'PATCH',
  path: '/api/v1/admin/organizations/[id]',
  params: adminV1IdParamsSchema,
  body: adminV1UpdateOrganizationBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationSchema),
  },
})

export const adminV1ListOrganizationMembersContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations/[id]/members',
  params: adminV1IdParamsSchema,
  query: adminV1PaginationQuerySchema,
  response: {
    mode: 'json',
    schema: adminV1ListResponseSchema(adminV1MemberDetailSchema),
  },
})

export const adminV1AddOrganizationMemberContract = defineRouteContract({
  method: 'POST',
  path: '/api/v1/admin/organizations/[id]/members',
  params: adminV1IdParamsSchema,
  body: adminV1AddOrganizationMemberBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationMemberMutationResultSchema),
  },
})

export const adminV1GetOrganizationMemberContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations/[id]/members/[memberId]',
  params: adminV1OrganizationMemberParamsSchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1MemberDetailSchema),
  },
})

export const adminV1UpdateOrganizationMemberContract = defineRouteContract({
  method: 'PATCH',
  path: '/api/v1/admin/organizations/[id]/members/[memberId]',
  params: adminV1OrganizationMemberParamsSchema,
  body: adminV1UpdateOrganizationMemberBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1MemberSchema),
  },
})

export const adminV1RemoveOrganizationMemberContract = defineRouteContract({
  method: 'DELETE',
  path: '/api/v1/admin/organizations/[id]/members/[memberId]',
  params: adminV1OrganizationMemberParamsSchema,
  query: adminV1RemoveOrganizationMemberQuerySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1RemoveOrganizationMemberResultSchema),
  },
})

export const adminV1GetOrganizationBillingContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations/[id]/billing',
  params: adminV1IdParamsSchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationBillingSummarySchema),
  },
})

export const adminV1UpdateOrganizationBillingContract = defineRouteContract({
  method: 'PATCH',
  path: '/api/v1/admin/organizations/[id]/billing',
  params: adminV1IdParamsSchema,
  body: adminV1UpdateOrganizationBillingBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1OrganizationBillingUpdateResultSchema),
  },
})

export const adminV1GetOrganizationSeatsContract = defineRouteContract({
  method: 'GET',
  path: '/api/v1/admin/organizations/[id]/seats',
  params: adminV1IdParamsSchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1SeatAnalyticsSchema),
  },
})

export const adminV1TransferOwnershipContract = defineRouteContract({
  method: 'POST',
  path: '/api/v1/admin/organizations/[id]/transfer-ownership',
  params: adminV1IdParamsSchema,
  body: adminV1TransferOwnershipBodySchema,
  response: {
    mode: 'json',
    schema: adminV1SingleResponseSchema(adminV1TransferOwnershipResultSchema),
  },
})

export type AdminV1ListOrganizationsResponse = ContractJsonResponse<
  typeof adminV1ListOrganizationsContract
>
export type AdminV1CreateOrganizationResponse = ContractJsonResponse<
  typeof adminV1CreateOrganizationContract
>
export type AdminV1GetOrganizationResponse = ContractJsonResponse<
  typeof adminV1GetOrganizationContract
>
export type AdminV1UpdateOrganizationResponse = ContractJsonResponse<
  typeof adminV1UpdateOrganizationContract
>
export type AdminV1ListOrganizationMembersResponse = ContractJsonResponse<
  typeof adminV1ListOrganizationMembersContract
>
export type AdminV1AddOrganizationMemberResponse = ContractJsonResponse<
  typeof adminV1AddOrganizationMemberContract
>
export type AdminV1GetOrganizationMemberResponse = ContractJsonResponse<
  typeof adminV1GetOrganizationMemberContract
>
export type AdminV1UpdateOrganizationMemberResponse = ContractJsonResponse<
  typeof adminV1UpdateOrganizationMemberContract
>
export type AdminV1RemoveOrganizationMemberResponse = ContractJsonResponse<
  typeof adminV1RemoveOrganizationMemberContract
>
export type AdminV1GetOrganizationBillingResponse = ContractJsonResponse<
  typeof adminV1GetOrganizationBillingContract
>
export type AdminV1UpdateOrganizationBillingResponse = ContractJsonResponse<
  typeof adminV1UpdateOrganizationBillingContract
>
export type AdminV1GetOrganizationSeatsResponse = ContractJsonResponse<
  typeof adminV1GetOrganizationSeatsContract
>
export type AdminV1TransferOwnershipResponse = ContractJsonResponse<
  typeof adminV1TransferOwnershipContract
>
