import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  users: defineTable({
    tenantId: v.string(),
    name: v.string(),
    email: v.string(),
    role: v.optional(v.string()),
    avatarUrl: v.optional(v.string()),
    teams: v.optional(v.array(v.string())),
    companyId: v.optional(v.id("companies")),
  })
    .index("by_tenant_email", ["tenantId", "email"]) 
    .index("by_tenant_role", ["tenantId", "role"])
    .index("by_tenant", ["tenantId"])
    .index("by_tenant_company", ["tenantId", "companyId"]),

  companies: defineTable({
    tenantId: v.string(),
    name: v.string(),
    slug: v.string(),
    provisioningCode: v.optional(v.string()),
    isAvulso: v.optional(v.boolean()),
    contractedHoursPerMonth: v.optional(v.number()),
    cnpj: v.optional(v.string()),
    domain: v.optional(v.string()),
    phone: v.optional(v.string()),
    description: v.optional(v.string()),
    address: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_tenant_slug", ["tenantId", "slug"])
    .index("by_tenant", ["tenantId"])
    .index("by_provisioning_code", ["provisioningCode"]),

  alerts: defineTable({
    tenantId: v.string(),
    companyId: v.optional(v.id("companies")),
    companyName: v.string(),
    usagePct: v.number(),
    threshold: v.number(),
    range: v.string(),
    recipients: v.array(v.string()),
    createdAt: v.number(),
    deliveredCount: v.number(),
  })
    .index("by_tenant_created", ["tenantId", "createdAt"]) 
    .index("by_tenant", ["tenantId"]),

  queues: defineTable({
    tenantId: v.string(),
    name: v.string(),
    slug: v.string(),
    teamId: v.optional(v.id("teams")),
  })
    .index("by_tenant_slug", ["tenantId", "slug"])
    .index("by_tenant", ["tenantId"]),

  teams: defineTable({
    tenantId: v.string(),
    name: v.string(),
    description: v.optional(v.string()),
  }).index("by_tenant_name", ["tenantId", "name"]),

  slaPolicies: defineTable({
    tenantId: v.string(),
    name: v.string(),
    description: v.optional(v.string()),
    timeToFirstResponse: v.optional(v.number()), // minutes
    timeToResolution: v.optional(v.number()), // minutes
  }).index("by_tenant_name", ["tenantId", "name"]),

  tickets: defineTable({
    tenantId: v.string(),
    reference: v.number(),
    subject: v.string(),
    summary: v.optional(v.string()),
    description: v.optional(v.string()),
    status: v.string(),
    priority: v.string(),
    channel: v.string(),
    queueId: v.optional(v.id("queues")),
    categoryId: v.optional(v.id("ticketCategories")),
    subcategoryId: v.optional(v.id("ticketSubcategories")),
    requesterId: v.id("users"),
    assigneeId: v.optional(v.id("users")),
    companyId: v.optional(v.id("companies")),
    working: v.optional(v.boolean()),
    slaPolicyId: v.optional(v.id("slaPolicies")),
    dueAt: v.optional(v.number()), // ms since epoch
    firstResponseAt: v.optional(v.number()),
    resolvedAt: v.optional(v.number()),
    closedAt: v.optional(v.number()),
    updatedAt: v.number(),
    createdAt: v.number(),
    tags: v.optional(v.array(v.string())),
    customFields: v.optional(
      v.array(
        v.object({
          fieldId: v.id("ticketFields"),
          fieldKey: v.string(),
          label: v.string(),
          type: v.string(),
          value: v.any(),
          displayValue: v.optional(v.string()),
        })
      )
    ),
    totalWorkedMs: v.optional(v.number()),
    internalWorkedMs: v.optional(v.number()),
    externalWorkedMs: v.optional(v.number()),
    activeSessionId: v.optional(v.id("ticketWorkSessions")),
  })
    .index("by_tenant_status", ["tenantId", "status"]) 
    .index("by_tenant_queue", ["tenantId", "queueId"]) 
    .index("by_tenant_assignee", ["tenantId", "assigneeId"]) 
    .index("by_tenant_reference", ["tenantId", "reference"])
    .index("by_tenant_company", ["tenantId", "companyId"])
    .index("by_tenant", ["tenantId"]),

  ticketComments: defineTable({
    ticketId: v.id("tickets"),
    authorId: v.id("users"),
    visibility: v.string(), // PUBLIC | INTERNAL
    body: v.string(),
    authorSnapshot: v.optional(
      v.object({
        name: v.string(),
        email: v.optional(v.string()),
        avatarUrl: v.optional(v.string()),
        teams: v.optional(v.array(v.string())),
      })
    ),
    attachments: v.optional(
      v.array(
        v.object({
          storageId: v.id("_storage"),
          name: v.string(),
          size: v.optional(v.number()),
          type: v.optional(v.string()),
        })
      )
    ),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_ticket", ["ticketId"])
    .index("by_author", ["authorId"]),

  ticketEvents: defineTable({
    ticketId: v.id("tickets"),
    type: v.string(),
    payload: v.optional(v.any()),
    createdAt: v.number(),
  }).index("by_ticket", ["ticketId"]),

  commentTemplates: defineTable({
    tenantId: v.string(),
    kind: v.optional(v.string()),
    title: v.string(),
    body: v.string(),
    createdBy: v.id("users"),
    updatedBy: v.optional(v.id("users")),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_tenant", ["tenantId"])
    .index("by_tenant_title", ["tenantId", "title"])
    .index("by_tenant_kind", ["tenantId", "kind"]),

  ticketWorkSessions: defineTable({
    ticketId: v.id("tickets"),
    agentId: v.id("users"),
    workType: v.optional(v.string()), // INTERNAL | EXTERNAL
    startedAt: v.number(),
    stoppedAt: v.optional(v.number()),
    durationMs: v.optional(v.number()),
    pauseReason: v.optional(v.string()),
    pauseNote: v.optional(v.string()),
  })
    .index("by_ticket", ["ticketId"])
    .index("by_ticket_agent", ["ticketId", "agentId"]),

  ticketCategories: defineTable({
    tenantId: v.string(),
    name: v.string(),
    slug: v.string(),
    description: v.optional(v.string()),
    order: v.number(),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_tenant_slug", ["tenantId", "slug"])
    .index("by_tenant_order", ["tenantId", "order"])
    .index("by_tenant", ["tenantId"]),

  ticketSubcategories: defineTable({
    tenantId: v.string(),
    categoryId: v.id("ticketCategories"),
    name: v.string(),
    slug: v.string(),
    order: v.number(),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_category_order", ["categoryId", "order"])
    .index("by_category_slug", ["categoryId", "slug"])
    .index("by_tenant_slug", ["tenantId", "slug"]),

  ticketFields: defineTable({
    tenantId: v.string(),
    key: v.string(),
    label: v.string(),
    type: v.string(),
    description: v.optional(v.string()),
    required: v.boolean(),
    order: v.number(),
    options: v.optional(
      v.array(
        v.object({
          value: v.string(),
          label: v.string(),
        })
      )
    ),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_tenant_key", ["tenantId", "key"])
    .index("by_tenant_order", ["tenantId", "order"])
    .index("by_tenant", ["tenantId"]),

  userInvites: defineTable({
    tenantId: v.string(),
    inviteId: v.string(),
    email: v.string(),
    name: v.optional(v.string()),
    role: v.string(),
    status: v.string(),
    token: v.string(),
    expiresAt: v.number(),
    createdAt: v.number(),
    createdById: v.optional(v.string()),
    acceptedAt: v.optional(v.number()),
    acceptedById: v.optional(v.string()),
    revokedAt: v.optional(v.number()),
    revokedById: v.optional(v.string()),
    revokedReason: v.optional(v.string()),
  })
    .index("by_tenant", ["tenantId"])
    .index("by_token", ["tenantId", "token"])
    .index("by_invite", ["tenantId", "inviteId"]),

  machines: defineTable({
    tenantId: v.string(),
    companyId: v.optional(v.id("companies")),
    companySlug: v.optional(v.string()),
    authUserId: v.optional(v.string()),
    authEmail: v.optional(v.string()),
    persona: v.optional(v.string()),
    assignedUserId: v.optional(v.id("users")),
    assignedUserEmail: v.optional(v.string()),
    assignedUserName: v.optional(v.string()),
    assignedUserRole: v.optional(v.string()),
    hostname: v.string(),
    osName: v.string(),
    osVersion: v.optional(v.string()),
    architecture: v.optional(v.string()),
    macAddresses: v.array(v.string()),
    serialNumbers: v.array(v.string()),
    fingerprint: v.string(),
    metadata: v.optional(v.any()),
    lastHeartbeatAt: v.optional(v.number()),
    status: v.optional(v.string()),
    isActive: v.optional(v.boolean()),
    createdAt: v.number(),
    updatedAt: v.number(),
    registeredBy: v.optional(v.string()),
  })
    .index("by_tenant", ["tenantId"])
    .index("by_tenant_company", ["tenantId", "companyId"])
    .index("by_tenant_fingerprint", ["tenantId", "fingerprint"])
    .index("by_tenant_assigned_email", ["tenantId", "assignedUserEmail"])
    .index("by_auth_email", ["authEmail"]),

  machineAlerts: defineTable({
    tenantId: v.string(),
    machineId: v.id("machines"),
    companyId: v.optional(v.id("companies")),
    kind: v.string(),
    message: v.string(),
    severity: v.string(),
    createdAt: v.number(),
  })
    .index("by_machine_created", ["machineId", "createdAt"])
    .index("by_tenant_created", ["tenantId", "createdAt"])
    .index("by_tenant_machine", ["tenantId", "machineId"]),

  machineTokens: defineTable({
    tenantId: v.string(),
    machineId: v.id("machines"),
    tokenHash: v.string(),
    expiresAt: v.number(),
    revoked: v.boolean(),
    createdAt: v.number(),
    lastUsedAt: v.optional(v.number()),
    usageCount: v.optional(v.number()),
    type: v.optional(v.string()),
  })
    .index("by_token_hash", ["tokenHash"])
    .index("by_machine", ["machineId"])
    .index("by_tenant_machine", ["tenantId", "machineId"]),
});
