Source: models/eventModel.js

/**
 * @fileoverview Event Model for Satoshi Showdown.
 * Defines the structure and constraints for events within the Satoshi Showdown platform.
 * Encapsulates event information, schedule, participation details, financial aspects, and metadata.
 * Instrumental in representing and managing event data in the application's database.
 *
 * @module models/Event
 * @requires mongoose - Mongoose library for MongoDB object modeling.
 * @requires uuid - UUID library for generating unique identifiers.
 */

const mongoose = require("mongoose");
const { v4: uuidv4 } = require("uuid");

/**
 * EventSchema: Defines structure and rules for event-related data.
 * Includes event name, type, schedule, participant information, and financial aspects.
 * Manages event lifecycle stages, open/closed status, and closure time.
 *
 * @typedef {Object} EventSchema
 * @property {string} eventId - Unique identifier.
 * @property {string} name - Event name.
 * @property {string} description - Event description.
 * @property {string} type - Event type.
 * @property {Date} startTime - Scheduled start time.
 * @property {Date} endTime - Scheduled end time.
 * @property {string} status - Event lifecycle status.
 * @property {number} entryFee - Participant entry fee.
 * @property {number} prizePool - Prize amount available.
 * @property {mongoose.Schema.Types.ObjectId} creator - Reference to the event creator.
 * @property {Array} participants - Array of participant references with join timestamps.
 * @property {number} maxParticipants - Maximum allowed participants.
 * @property {number} minParticipants - Minimum required participants.
 * @property {boolean} isOpen - Open status for new participants.
 * @property {Date} closedAt - Timestamp of event closure.
 * @property {Array} transactions - References to associated financial transactions.
 * @property {Array} winners - References to event winners.
 * @property {Object} config - Configuration details.
 * @property {string} streamingUrl - Live streaming URL.
 * @property {Object} streamingSchedule - Live streaming schedule.
 * @property {Array} bettingOptions - Betting options details.
 * @property {number} viewCount - Event view count.
 * @property {Array} feedback - User feedback references.
 * @property {Array} socialSharingLinks - Social sharing links.
 * @property {number} ageRestriction - Age restriction for participation.
 * @property {Array} geographicRestrictions - Geographic limitations.
 * @property {string} settlementType - Method used to determine the outcome of the event.
 * @property {Array} voteResults - Voting results from participants.
 * @property {boolean} isDisputed - Whether the event result is disputed.
 * @property {Array} disputeEvidence - Evidence submitted for disputed results.
 * @property {string} disputeResolutionStatus - Status of dispute resolution.
 * @property {string} settlementStatus - Status of event settlement.
 * @property {Object} finalOutcome - Final outcome details with winners and settlement time.
 */
const eventSchema = new mongoose.Schema(
  {
    eventId: { type: String, default: uuidv4, unique: true },
    name: { type: String, required: true },
    description: String,
    type: String,
    startTime: Date,
    endTime: Date,
    status: {
      type: String,
      enum: [
        "planning",
        "ready",
        "active",
        "settling",
        "completed",
        "cancelled",
      ],
      default: "planning",
    },
    entryFee: { type: Number, required: true, default: 0 },
    prizePool: { type: Number, required: true, default: 0 },
    creator: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    participants: [
      {
        userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
        depositAddress: String,
        userAddress: String,
        joinedAt: { type: Date, default: Date.now },
      },
    ],
    maxParticipants: { type: Number, required: true },
    minParticipants: { type: Number, required: true },
    isOpen: { type: Boolean, default: true },
    closedAt: Date,
    walletRef: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Wallet",
      required: true,
    },
    transactions: [
      { type: mongoose.Schema.Types.ObjectId, ref: "Transaction" },
    ],
    winners: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
    config: Object,
    streamingUrl: String,
    streamingSchedule: { start: Date, end: Date },
    bettingOptions: [
      {
        type: { type: String },
        description: String,
        odds: Number,
      },
    ],
    viewCount: { type: Number, default: 0 },
    feedback: [{ type: mongoose.Schema.Types.ObjectId, ref: "UserFeedback" }],
    socialSharingLinks: [String],
    ageRestriction: Number,
    geographicRestrictions: [String],
    settlementType: {
      type: String,
      enum: ["voting", "oracle", "referee", "automatic"],
      default: "voting",
      required: true,
    },
    voteResults: [
      {
        userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
        vote: { type: String, enum: ["win", "loss", "draw", "dispute"] },
        timestamp: { type: Date, default: Date.now },
      },
    ],
    isDisputed: { type: Boolean, default: false },
    disputeEvidence: [
      {
        userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
        evidenceUrl: String,
        submittedAt: { type: Date, default: Date.now },
      },
    ],
    disputeResolutionStatus: {
      type: String,
      enum: ["pending", "resolved", "escalated"],
      default: "pending",
    },
    settlementStatus: {
      type: String,
      enum: ["unsettled", "voting", "processing", "settled", "contested"],
      default: "unsettled",
    },
    finalOutcome: {
      winners: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
      settledAt: Date,
    },
  },
  { timestamps: true },
);

/**
 * Event model based on the defined schema.
 * Represents an event within the Satoshi Showdown platform, encapsulating all data and behaviors
 * related to event management. This includes event creation, modification, participant management,
 * and handling of associated financial transactions and user feedback.
 *
 * @typedef {mongoose.Model<module:models/Event~EventSchema>} EventModel
 */

const Event = mongoose.model("Event", eventSchema);
module.exports = Event;