import type { Static } from "@sinclair/typebox"
import type { Document } from "mongoose"
import { Type } from "@sinclair/typebox"
import type { PluginFastifyInstance } from "types"

/**
 * Base WorkSession Schema - Fields common to all operations
 */
const baseWorkSessionSchema = {
  userId: Type.Optional(Type.String()),
  accessType: Type.Optional(
    Type.String({ default: "anonymous", enum: ["anonymous"] }),
  ),
  compositionId: Type.Optional(Type.String()),
  project: Type.String(), // Project ID for payload wrapper (temporary solution)
  expiryDate: Type.Optional(Type.String({ format: "date-time" })),
  isActive: Type.Optional(Type.Boolean({ default: true })),
  permissions: Type.Optional(Type.Number({ default: 6 })),
  pluginData: Type.Optional(
    Type.Record(Type.String(), Type.Any(), { default: {} }),
  ),
  composition: Type.Optional(Type.Any()),
}

/**
 * Full WorkSession Schema - Used for response serialization and database model
 */
export const workSessionSchema = Type.Object(
  {
    _id: Type.String(),
    ...baseWorkSessionSchema,
    createdAt: Type.String({ format: "date-time" }),
    updatedAt: Type.String({ format: "date-time" }),
  },
  {
    $id: "#workSession/base",
    title: "core/workSession",
  },
)

/**
 * WorkSession Create Schema - For POST operations
 */
export const workSessionCreateSchema = Type.Object(
  {
    _id: Type.Optional(Type.String()),
    ...baseWorkSessionSchema,
  },
  {
    $id: "#workSession/create",
    title: "core/workSession-create",
  },
)

/**
 * WorkSession Update Schema - For PATCH operations
 */
export const workSessionUpdateSchema = Type.Object(
  {
    _id: Type.Optional(Type.String()),
    ...baseWorkSessionSchema,
  },
  {
    $id: "#workSession/update",
    title: "core/workSession-update",
  },
)

/**
 * Type Utilities
 */

type DateTimeFields = {
  createdAt: Date
  updatedAt: Date
}

type RawWorkSession = Static<typeof workSessionSchema>
export type WorkSession = Omit<RawWorkSession, keyof DateTimeFields> &
  DateTimeFields

type RawWorkSessionCreate = Static<typeof workSessionCreateSchema>
export type WorkSessionCreate = RawWorkSessionCreate

type RawWorkSessionUpdate = Static<typeof workSessionUpdateSchema>
export type WorkSessionUpdate = RawWorkSessionUpdate

export interface WorkSessionDoc extends Document, WorkSession {
  _id: string
}
export type AnyWorkSession = WorkSession | WorkSessionDoc

/** Shape of work session attached to req by authenticatedOrWorksession */
export interface RequestWorkSession {
  _id: string
  userId: string
  accessType: string
  compositionId: string
  project?: string
  expiryDate: Date
  isActive: boolean
  permissions?: number
  pluginData?: Record<string, unknown>
  composition?: unknown
}

/**
 * Register Schema/Type Generation for Shared Folder
 */
export const registerSchemas = (fastify: PluginFastifyInstance) => {
  fastify.registerSchema({
    schema: workSessionSchema,
    name: "WorkSession",
  })

  fastify.registerSchema({
    schema: workSessionCreateSchema,
    name: "WorkSessionCreate",
  })

  fastify.registerSchema({
    schema: workSessionUpdateSchema,
    name: "WorkSessionUpdate",
  })
}
