// src/modules/contact/contacts.model.ts

import { Schema, model } from 'mongoose';
import { paginate, toJSON } from '@/shared/utils/plugins/index';
import {
  IContactDoc,
  IContactModel,
  IContactPhone,
} from '@/modules/contacts/contacts.interface';

export const contactPhoneSchema = new Schema<IContactPhone>(
  {
    countryCode: { type: Number, required: true },
    number: { type: Number, required: true },
    isPrimary: { type: Boolean, default: false },
  },
  { _id: false },
);

const contactSchema = new Schema<IContactDoc>(
  {
    firstName: { type: String, required: true, trim: true },
    lastName: { type: String, trim: true },
    email: { type: String, trim: true, sparse: true },
    company: { type: Schema.Types.ObjectId, ref: 'Company' },
    phone: {
      type: [contactPhoneSchema],
      required: true,
      validate: {
        validator: (v: IContactPhone[]) => Array.isArray(v) && v.length > 0,
        message: 'At least one phone number is required',
      },
    },
    addressLine1: { type: String, trim: true },
    addressLine2: { type: String, trim: true },
    country: { type: Schema.Types.ObjectId, ref: 'Country' },
    state: { type: Schema.Types.ObjectId, ref: 'State' },
    city: { type: Schema.Types.ObjectId, ref: 'City' },
    pinCode: { type: Number, required: true },
    source: { type: Schema.Types.ObjectId, ref: 'Source' },
    companyName: { type: String, trim: true },
    position: { type: String, trim: true },
    workPhoneNumber: {
      type: String,
    },
    workEmail: { type: String, trim: true, sparse: true },
    createdBy: { type: Schema.Types.ObjectId, ref: 'User' },
    updatedBy: { type: Schema.Types.ObjectId, ref: 'User' },
    shortlisted: [{ type: Schema.Types.ObjectId, ref: 'individualProperties' }],
    removed: [{ type: Schema.Types.ObjectId, ref: 'individualProperties' }],
    companyId: {
      type: Schema.Types.ObjectId,
      ref: 'Company',
    },
    customFields: {
      type: Map,
      of: Schema.Types.Mixed,
      default: {},
    },
  },
  {
    timestamps: true,
    collation: { locale: 'en', strength: 1 },
  },
);

// contactSchema.index(
//   { email: 1 },
//   { unique: true, partialFilterExpression: { email: { $exists: true, $type: 'string' } } },
// );

contactSchema.index(
  { company: 1, 'phone.countryCode': 1, 'phone.number': 1 },
  {
    unique: true,
    partialFilterExpression: {
      company: { $type: 'objectId' },
      'phone.countryCode': { $exists: true },
      'phone.number': { $exists: true },
    },
  },
);

contactSchema.virtual('name').get(function () {
  const firstName = this.firstName || '';
  const lastName = this.lastName || '';
  return `${firstName} ${lastName}`.trim();
});

contactSchema.virtual('createdOn').get(function () {
  return this.createdAt ? this.createdAt.toISOString() : null;
});

contactSchema.virtual('updatedOn').get(function () {
  return this.updatedAt ? this.updatedAt.toISOString() : null;
});

contactSchema.virtual('primaryPhone').get(function () {
  let phone = this.phone?.find((p) => p.isPrimary) || null;
  return phone
    ? `+${phone.countryCode} ${phone.number}`
    : this.phone?.[0]
      ? `+${this.phone[0].countryCode} ${this.phone[0].number}`
      : null;
});

contactSchema.plugin(toJSON);
contactSchema.plugin(paginate);

export const Contact = model<IContactDoc, IContactModel>(
  'Contact',
  contactSchema,
);
