import { z } from 'zod'
import { UuidSchema } from '../../platform/utils/validation'

export const ClientStatusSchema = z.enum(['active', 'onboarding', 'paused', 'completed', 'churned'])
export const ClientSourceSchema = z
  .string()
  .trim()
  .min(1)
  .max(64)
  .regex(/^[a-z][a-z0-9_]*$/, 'Source must use lowercase letters, numbers, and underscores')

export const ClientIdParamsSchema = z
  .object({
    clientId: UuidSchema
  })
  .strict()

export const ListClientsQuerySchema = z
  .object({
    status: ClientStatusSchema.optional(),
    source: ClientSourceSchema.optional(),
    search: z.string().trim().min(1).max(255).optional(),
    limit: z.coerce.number().int().min(1).max(100).default(50),
    offset: z.coerce.number().int().min(0).default(0)
  })
  .strict()

export const ClientRefSchema = z.object({
  id: z.string(),
  name: z.string(),
  status: ClientStatusSchema
})

export const ClientResponseSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  name: z.string(),
  status: ClientStatusSchema,
  source: ClientSourceSchema,
  sourceDealId: z.string().nullable(),
  primaryCompanyId: z.string().nullable(),
  primaryContactId: z.string().nullable(),
  convertedAt: z.string().nullable(),
  metadata: z.record(z.string(), z.unknown()),
  createdAt: z.string(),
  updatedAt: z.string()
})

export const ClientDealRefSchema = z.object({
  id: z.string(),
  contactEmail: z.string(),
  stageKey: z.string().nullable(),
  stateKey: z.string().nullable(),
  updatedAt: z.string()
})

export const ClientProjectRefSchema = z.object({
  id: z.string(),
  name: z.string(),
  kind: z.string(),
  status: z.string(),
  updatedAt: z.string()
})

export const ClientCompanyRefSchema = z.object({
  id: z.string(),
  name: z.string(),
  domain: z.string().nullable(),
  status: z.string()
})

export const ClientContactRefSchema = z.object({
  id: z.string(),
  email: z.string(),
  firstName: z.string().nullable(),
  lastName: z.string().nullable(),
  title: z.string().nullable(),
  companyId: z.string().nullable(),
  status: z.string()
})

export const ClientLineageSchema = z.object({
  deals: z.array(ClientDealRefSchema),
  projects: z.array(ClientProjectRefSchema),
  companies: z.array(ClientCompanyRefSchema),
  contacts: z.array(ClientContactRefSchema)
})

export const ClientDetailResponseSchema = ClientResponseSchema.extend({
  lineage: ClientLineageSchema
})

export const ClientListResponseSchema = z.object({
  data: z.array(ClientResponseSchema),
  total: z.number().int().min(0),
  limit: z.number().int().min(1),
  offset: z.number().int().min(0)
})

export const ClientStatusResponseSchema = z.object({
  totalClients: z.number().int().min(0),
  byStatus: z.record(ClientStatusSchema, z.number().int().min(0)),
  linkedDeals: z.number().int().min(0),
  linkedProjects: z.number().int().min(0),
  linkedCompanies: z.number().int().min(0),
  linkedContacts: z.number().int().min(0)
})

export const CreateClientRequestSchema = z
  .object({
    name: z.string().trim().min(1).max(255),
    status: ClientStatusSchema.optional(),
    source: ClientSourceSchema.optional(),
    sourceDealId: UuidSchema.nullable().optional(),
    primaryCompanyId: UuidSchema.nullable().optional(),
    primaryContactId: UuidSchema.nullable().optional(),
    metadata: z.record(z.string(), z.unknown()).nullable().optional()
  })
  .strict()

export const UpdateClientRequestSchema = z
  .object({
    name: z.string().trim().min(1).max(255).optional(),
    status: ClientStatusSchema.optional(),
    source: ClientSourceSchema.optional(),
    sourceDealId: UuidSchema.nullable().optional(),
    primaryCompanyId: UuidSchema.nullable().optional(),
    primaryContactId: UuidSchema.nullable().optional(),
    metadata: z.record(z.string(), z.unknown()).nullable().optional()
  })
  .strict()
  .refine((data) => Object.keys(data).length > 0, {
    message: 'At least one field must be provided'
  })

export const ClientSchemas = {
  ClientStatus: ClientStatusSchema,
  ClientSource: ClientSourceSchema,
  ClientIdParams: ClientIdParamsSchema,
  ListClientsQuery: ListClientsQuerySchema,
  ClientRef: ClientRefSchema,
  ClientResponse: ClientResponseSchema,
  ClientDealRef: ClientDealRefSchema,
  ClientProjectRef: ClientProjectRefSchema,
  ClientCompanyRef: ClientCompanyRefSchema,
  ClientContactRef: ClientContactRefSchema,
  ClientLineage: ClientLineageSchema,
  ClientDetailResponse: ClientDetailResponseSchema,
  ClientListResponse: ClientListResponseSchema,
  ClientStatusResponse: ClientStatusResponseSchema,
  CreateClientRequest: CreateClientRequestSchema,
  UpdateClientRequest: UpdateClientRequestSchema
}

export type ClientStatus = z.infer<typeof ClientStatusSchema>
export type ClientSource = z.infer<typeof ClientSourceSchema>
export type ClientIdParams = z.infer<typeof ClientIdParamsSchema>
export type ListClientsQuery = z.infer<typeof ListClientsQuerySchema>
export type ClientRef = z.infer<typeof ClientRefSchema>
export type ClientResponse = z.infer<typeof ClientResponseSchema>
export type ClientDealRef = z.infer<typeof ClientDealRefSchema>
export type ClientProjectRef = z.infer<typeof ClientProjectRefSchema>
export type ClientCompanyRef = z.infer<typeof ClientCompanyRefSchema>
export type ClientContactRef = z.infer<typeof ClientContactRefSchema>
export type ClientLineage = z.infer<typeof ClientLineageSchema>
export type ClientDetailResponse = z.infer<typeof ClientDetailResponseSchema>
export type ClientListResponse = z.infer<typeof ClientListResponseSchema>
export type ClientStatusResponse = z.infer<typeof ClientStatusResponseSchema>
export type CreateClientRequest = z.infer<typeof CreateClientRequestSchema>
export type UpdateClientRequest = z.infer<typeof UpdateClientRequestSchema>
