import { Schema, model } from 'mongoose';
import { paginate, toJSON } from '@/shared/utils/plugins';
import {
  ICPCompanyDoc,
  ICPCompanyModel,
  ICPContactDoc,
  ICPContactModel,
  ICPPaymentDoc,
  ICPPaymentModel,
  ICPPhone,
} from './channelPartner.interface';

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

const cpCompanySchema = new Schema<ICPCompanyDoc>(
  {
    companyName: { type: String, required: true, trim: true },
    website: { type: String, trim: true },
    address: { type: String, trim: true },
    city: { type: String, trim: true },
    state: { type: String, trim: true },
    country: { type: String, trim: true, default: 'India' },
    baseCommissionRate: { type: Number, default: 0 },
    notes: { type: String, trim: true },
    status: {
      type: String,
      enum: ['Active', 'Inactive'],
      default: 'Active',
    },
    company: { type: Schema.Types.ObjectId, ref: 'Company', required: true },
    createdBy: { type: Schema.Types.ObjectId, ref: 'User' },
    updatedBy: { type: Schema.Types.ObjectId, ref: 'User' },
  },
  {
    timestamps: true,
    collation: { locale: 'en', strength: 1 },
  },
);

cpCompanySchema.index({ company: 1, companyName: 1 }, { unique: true });

cpCompanySchema.plugin(toJSON);
cpCompanySchema.plugin(paginate);

export const CPCompany = model<ICPCompanyDoc, ICPCompanyModel>(
  'CPCompany',
  cpCompanySchema,
);

const cpContactSchema = new Schema<ICPContactDoc>(
  {
    firstName: { type: String, required: true, trim: true },
    lastName: { type: String, trim: true },
    phone: {
      type: [cpPhoneSchema],
      required: true,
      validate: {
        validator: (v: ICPPhone[]) => Array.isArray(v) && v.length > 0,
        message: 'At least one phone number is required',
      },
    },
    email: { type: String, trim: true, sparse: true },
    isPrimary: { type: Boolean, default: false },
    status: {
      type: String,
      enum: ['Active', 'Inactive'],
      default: 'Active',
    },
    cpCompany: {
      type: Schema.Types.ObjectId,
      ref: 'CPCompany',
      required: true,
    },
    company: { type: Schema.Types.ObjectId, ref: 'Company', required: true },
    createdBy: { type: Schema.Types.ObjectId, ref: 'User' },
    updatedBy: { type: Schema.Types.ObjectId, ref: 'User' },
  },
  {
    timestamps: true,
    collation: { locale: 'en', strength: 1 },
  },
);

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

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

cpContactSchema.plugin(toJSON);
cpContactSchema.plugin(paginate);

export const CPContact = model<ICPContactDoc, ICPContactModel>(
  'CPContact',
  cpContactSchema,
);

const cpPaymentSchema = new Schema<ICPPaymentDoc>(
  {
    cpCompany: {
      type: Schema.Types.ObjectId,
      ref: 'CPCompany',
      required: true,
    },
    company: { type: Schema.Types.ObjectId, ref: 'Company', required: true },
    paymentDate: { type: Date, required: true },
    amountPaid: { type: Number, required: true },
    notes: { type: String, trim: true },
    createdBy: { type: Schema.Types.ObjectId, ref: 'User' },
    updatedBy: { type: Schema.Types.ObjectId, ref: 'User' },
  },
  {
    timestamps: true,
  },
);

cpPaymentSchema.plugin(toJSON);
cpPaymentSchema.plugin(paginate);

export const CPPayment = model<ICPPaymentDoc, ICPPaymentModel>(
  'CPPayment',
  cpPaymentSchema,
);
