import { z } from "zod"

export const ticketStatusSchema = z.enum([
  "PENDING",
  "AWAITING_ATTENDANCE",
  "PAUSED",
  "RESOLVED",
])

export type TicketStatus = z.infer<typeof ticketStatusSchema>

const slaStatusSchema = z.enum(["pending", "met", "breached", "n/a"])
const slaTimeModeSchema = z.enum(["business", "calendar"])
export const visitStatusSchema = z.enum(["scheduled", "en_route", "in_service", "done", "no_show", "canceled"])
export type VisitStatus = z.infer<typeof visitStatusSchema>

export const ticketSlaSnapshotSchema = z.object({
  categoryId: z.string().optional(),
  categoryName: z.string().optional(),
  priority: z.string(),
  responseTargetMinutes: z.number().nullable().optional(),
  responseMode: slaTimeModeSchema.optional(),
  solutionTargetMinutes: z.number().nullable().optional(),
  solutionMode: slaTimeModeSchema.optional(),
  alertThreshold: z.number().optional(),
  pauseStatuses: z.array(z.string()).default([]),
})

export type TicketSlaSnapshot = z.infer<typeof ticketSlaSnapshotSchema>

export const ticketPrioritySchema = z.enum(["LOW", "MEDIUM", "HIGH", "URGENT"])
export type TicketPriority = z.infer<typeof ticketPrioritySchema>

export const ticketChannelSchema = z.enum([
  "EMAIL",
  "WHATSAPP",
  "CHAT",
  "PHONE",
  "API",
  "MANUAL",
])
export type TicketChannel = z.infer<typeof ticketChannelSchema>

export const commentVisibilitySchema = z.enum(["PUBLIC", "INTERNAL"])
export type CommentVisibility = z.infer<typeof commentVisibilitySchema>

export const userSummarySchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
  avatarUrl: z.string().url().optional(),
  teams: z.array(z.string()).default([]),
})
export type UserSummary = z.infer<typeof userSummarySchema>

export const ticketCompanySummarySchema = z.object({
  id: z.string(),
  name: z.string(),
  isAvulso: z.boolean().optional(),
})
export type TicketCompanySummary = z.infer<typeof ticketCompanySummarySchema>

export const ticketMachineSummarySchema = z.object({
  id: z.string().nullable(),
  hostname: z.string().nullable().optional(),
  persona: z.string().nullable().optional(),
  assignedUserName: z.string().nullable().optional(),
  assignedUserEmail: z.string().nullable().optional(),
  status: z.string().nullable().optional(),
})
export type TicketMachineSummary = z.infer<typeof ticketMachineSummarySchema>

export const ticketCategorySummarySchema = z.object({
  id: z.string(),
  name: z.string(),
})
export type TicketCategorySummary = z.infer<typeof ticketCategorySummarySchema>

export const ticketSubcategorySummarySchema = z.object({
  id: z.string(),
  name: z.string(),
  categoryId: z.string().optional(),
})
export type TicketSubcategorySummary = z.infer<typeof ticketSubcategorySummarySchema>

export const ticketAgentWorkTotalSchema = z.object({
  agentId: z.string(),
  agentName: z.string().nullable().optional(),
  agentEmail: z.string().nullable().optional(),
  avatarUrl: z.string().nullable().optional(),
  totalWorkedMs: z.number(),
  internalWorkedMs: z.number().optional().default(0),
  externalWorkedMs: z.number().optional().default(0),
})
export type TicketAgentWorkTotal = z.infer<typeof ticketAgentWorkTotalSchema>

export const ticketCommentSchema = z.object({
  id: z.string(),
  author: userSummarySchema,
  visibility: commentVisibilitySchema,
  body: z.string(),
  attachments: z
    .array(
      z.object({
        id: z.string(),
        name: z.string(),
        size: z.number().optional(),
        type: z.string().optional(),
        url: z.string().url().optional(),
      })
    )
    .default([]),
  createdAt: z.coerce.date(),
  updatedAt: z.coerce.date(),
})
export type TicketComment = z.infer<typeof ticketCommentSchema>

export const ticketEventSchema = z.object({
  id: z.string(),
  type: z.string(),
  payload: z.record(z.string(), z.any()).optional(),
  createdAt: z.coerce.date(),
})
export type TicketEvent = z.infer<typeof ticketEventSchema>

export const ticketFieldTypeSchema = z.enum(["text", "number", "select", "date", "boolean"])
export type TicketFieldType = z.infer<typeof ticketFieldTypeSchema>

export const ticketCustomFieldValueSchema = z.object({
  label: z.string(),
  type: ticketFieldTypeSchema,
  value: z.union([z.string(), z.number(), z.boolean(), z.coerce.date()]).optional(),
  displayValue: z.string().optional(),
})
export type TicketCustomFieldValue = z.infer<typeof ticketCustomFieldValueSchema>

export const checklistItemTypeSchema = z.enum(["checkbox", "question"])
export type ChecklistItemType = z.infer<typeof checklistItemTypeSchema>

export const ticketChecklistItemSchema = z.object({
  id: z.string(),
  text: z.string(),
  description: z.string().optional(),
  type: checklistItemTypeSchema.optional(),
  options: z.array(z.string()).optional(),
  answer: z.string().optional(),
  done: z.boolean(),
  required: z.boolean().optional(),
  templateId: z.string().optional(),
  templateItemId: z.string().optional(),
  templateDescription: z.string().optional(),
  createdAt: z.number().optional(),
  createdBy: z.string().optional(),
  doneAt: z.number().optional(),
  doneBy: z.string().optional(),
})
export type TicketChecklistItem = z.infer<typeof ticketChecklistItemSchema>

export const ticketSchema = z.object({
  id: z.string(),
  reference: z.number(),
  tenantId: z.string(),
  subject: z.string(),
  summary: z.string().optional(),
  status: ticketStatusSchema,
  priority: ticketPrioritySchema,
  channel: ticketChannelSchema,
  queue: z.string().nullable(),
  requester: userSummarySchema,
  assignee: userSummarySchema.nullable(),
  company: ticketCompanySummarySchema.optional().nullable(),
  machine: ticketMachineSummarySchema.nullable().optional(),
  slaPolicy: z
    .object({
      id: z.string(),
      name: z.string(),
      targetMinutesToFirstResponse: z.number().nullable(),
      targetMinutesToResolution: z.number().nullable(),
    })
    .nullable(),
  slaSnapshot: ticketSlaSnapshotSchema.nullable().optional(),
  slaResponseDueAt: z.coerce.date().nullable().optional(),
  slaSolutionDueAt: z.coerce.date().nullable().optional(),
  slaResponseStatus: slaStatusSchema.nullable().optional(),
  slaSolutionStatus: slaStatusSchema.nullable().optional(),
  slaPausedAt: z.coerce.date().nullable().optional(),
  slaPausedBy: z.string().nullable().optional(),
  slaPausedMs: z.number().nullable().optional(),
  dueAt: z.coerce.date().nullable(),
  visitStatus: visitStatusSchema.nullable().optional(),
  visitPerformedAt: z.coerce.date().nullable().optional(),
  firstResponseAt: z.coerce.date().nullable(),
  resolvedAt: z.coerce.date().nullable(),
  closedAt: z.coerce.date().nullable().optional(),
  updatedAt: z.coerce.date(),
  createdAt: z.coerce.date(),
  tags: z.array(z.string()).default([]),
  lastTimelineEntry: z.string().nullable().optional(),
  metrics: z
    .object({
      timeWaitingMinutes: z.number().nullable(),
      timeOpenedMinutes: z.number().nullable(),
    })
    .nullable(),
  relatedTicketIds: z.array(z.string()).optional(),
  resolvedWithTicketId: z.string().nullable().optional(),
  reopenDeadline: z.number().nullable().optional(),
  reopenWindowDays: z.number().nullable().optional(),
  reopenedAt: z.number().nullable().optional(),
  reopenedBy: z.string().nullable().optional(),
  chatEnabled: z.boolean().optional(),
  formTemplate: z.string().nullable().optional(),
  formTemplateLabel: z.string().nullable().optional(),
  csatScore: z.number().nullable().optional(),
  csatMaxScore: z.number().nullable().optional(),
  csatComment: z.string().nullable().optional(),
  csatRatedAt: z.coerce.date().nullable().optional(),
  csatRatedBy: z.string().nullable().optional(),
  category: ticketCategorySummarySchema.nullable().optional(),
  subcategory: ticketSubcategorySummarySchema.nullable().optional(),
  checklist: z.array(ticketChecklistItemSchema).default([]),
  workSummary: z
    .object({
      totalWorkedMs: z.number(),
      internalWorkedMs: z.number().optional().default(0),
      externalWorkedMs: z.number().optional().default(0),
      serverNow: z.number().optional(),
      activeSession: z
        .object({
          id: z.string(),
          agentId: z.string(),
          startedAt: z.coerce.date(),
          workType: z.string().optional(),
        })
        .nullable(),
      perAgentTotals: z.array(ticketAgentWorkTotalSchema).optional(),
    })
    .nullable()
    .optional(),
})
export type Ticket = z.infer<typeof ticketSchema>

export const ticketWithDetailsSchema = ticketSchema.extend({
  description: z.string().optional(),
  customFields: z.record(z.string(), ticketCustomFieldValueSchema).optional(),
  timeline: z.array(ticketEventSchema),
  comments: z.array(ticketCommentSchema),
})
export type TicketWithDetails = z.infer<typeof ticketWithDetailsSchema>

export const ticketQueueSummarySchema = z.object({
  id: z.string(),
  name: z.string(),
  pending: z.number(),
  inProgress: z.number(),
  paused: z.number(),
  breached: z.number(),
})
export type TicketQueueSummary = z.infer<typeof ticketQueueSummarySchema>

export const ticketPlayContextSchema = z.object({
  queue: ticketQueueSummarySchema,
  nextTicket: ticketSchema.nullable(),
})
export type TicketPlayContext = z.infer<typeof ticketPlayContextSchema>
