import mongoose from "mongoose";

const channelSchema = new mongoose.Schema(
  {
    name: { type: String, required: true, trim: true },
    description: { type: String, trim: true },
    type: {
      type: String,
      enum: ["general", "project", "team", "announcement", "private", "group"],
      default: "general",
      index: true,
    },
    groupType: {
      type: String,
      enum: [
        "employee-only",
        "employee-intern",
        "employee-student",
        "all-staff",
      ],
      index: true,
    },
    allowedRoles: [
      {
        type: String,
        enum: ["admin", "employee", "intern", "student", "customer"],
      },
    ],
    category: {
      type: String,
      enum: [
        "graphics-design",
        "web-development",
        "ui-ux-design",
        "digital-marketing",
        "video-production",
        "general",
      ],
    },
    isPrivate: { type: Boolean, default: false },
    members: [
      { type: mongoose.Schema.Types.ObjectId, ref: "User", index: true },
    ],
    createdBy: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    isPinned: { type: Boolean, default: false },
    lastMessageAt: { type: Date },
  },
  { timestamps: true }
);

const attachmentSchema = new mongoose.Schema(
  {
    filename: { type: String, trim: true },
    url: { type: String, trim: true },
    type: { type: String, enum: ["image", "file"] },
  },
  { _id: false }
);

const messageSchema = new mongoose.Schema(
  {
    channelId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Channel",
      required: true,
      index: true,
    },
    senderId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
      index: true,
    },
    text: { type: String, trim: true, maxlength: 5000 },
    attachments: { type: [attachmentSchema], default: [] },
    isEdited: { type: Boolean, default: false },
    editedAt: { type: Date },
    replyTo: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Message",
    },
  },
  { timestamps: true }
);

messageSchema.pre("validate", function (next) {
  const hasText = typeof this.text === "string" && this.text.trim().length > 0;
  const hasAttachments =
    Array.isArray(this.attachments) && this.attachments.length > 0;
  if (!hasText && !hasAttachments) {
    this.invalidate(
      "text",
      "Message must include text or at least one attachment"
    );
  }
  next();
});

// Update channel's lastMessageAt on new message
messageSchema.post("save", async function () {
  await mongoose.model("Channel").findByIdAndUpdate(this.channelId, {
    lastMessageAt: this.createdAt,
  });
});

export const Channel = mongoose.model("Channel", channelSchema);
export const Message = mongoose.model("Message", messageSchema);
