import { Document, Model, Types } from 'mongoose';

/**
 * Base interface for common property fields
 */
export interface IBaseProperty {
  // Basic Details
  title: string;
  description: string;
  propertyType: string;
  subcategory: string;
  category: string;
  listingType: 'sell' | 'rent' | 'lease' | 'preLease';
  reraId?: string;
  configuration?: string;
  project?: string;
  status?: 'active' | 'inactive' | 'draft';

  // Property Details
  carpetArea: string;
  builtUpArea?: string;
  superBuiltUpArea?: string;
  length?: string;
  width?: string;
  bedrooms?: string;
  bathrooms?: string;
  balconies?: string;
  totalFloors?: string;
  floorNumber?: string;
  carParking?: string;
  furnishingStatus?: string;
  ageOfProperty?: string;
  possessionStatus?: string;

  // Commercial specific fields
  pantry?: string;
  parking?: string;
  washroom?: string;
  cabin?: string;

  // Location Details
  address: string;
  locality: string;
  city: string;
  pincode: string;
  facing?: string;
  latitude?: number;
  longitude?: number;
  placeId?: string;

  // Owner Details
  ownerName: string;
  ownerContact: string;
  ownerEmail?: string;

  // Additional Details
  amenities?: string[];
  tags?: string[];
  media?: string[];
  source?: Array<{
    sourceProjectId: string;
    id: string;
  }>;
  facilities?: Map<string, never>;

  // Visibility fields
  visibleToUsers?: Types.ObjectId[];
  visibleToTeams?: Types.ObjectId[];
  isPublicVisibility?: boolean;

  // Audit fields
  createdBy?: string;
  updatedBy?: string;
  createdAt?: Date;
  updatedAt?: Date;

  companyId?: string;

  // Custom Fields
  customFields?: {
    [key: string]: string;
  };

  isSharing?: boolean;
}

/**
 * Interface for Sell property type
 */
export interface ISellProperty {
  price: string;
  totalPrice?: string;
  ownershipType?: string;
  brokerageAvailable?: string;
  brokerageAmount?: string;
  availability?: string;
}

/**
 * Interface for Rent property type
 */
export interface IRentProperty {
  monthlyRent: string;
  securityDeposit: string;
  maintenanceCharges: string;
  brokerageAvailable?: string;
  brokerageAmount?: string;
  lockInPeriod: string;
  leaseDuration: string;
  agreementType: string;
  availableFrom?: Date;
}

/**
 * Interface for Lease property type
 */
export interface ILeaseProperty {
  monthlyRent: string;
  securityDeposit: string;
  maintenanceCharges: string;
  lockInPeriod: string;
  leaseDuration: string;
  agreementType: string;
}

/**
 * Interface for Pre-Leased property type
 */
export interface IPreLeasedProperty {
  monthlyRent: string;
  tenantName: string;
  leaseDuration: string;
  lockInPeriod: string;
  roiPercentage: string;
  leaseStartDate: Date;
  leaseEndDate: Date;
}

/**
 * Combined interface representing a Property document in MongoDB
 */
export type IProperty = IBaseProperty &
  Partial<ISellProperty & IRentProperty & ILeaseProperty & IPreLeasedProperty>;

export interface IPropertyDoc extends IProperty, Document {}

export interface IPropertyModel extends Model<IPropertyDoc> {
  paginate(
    filter: Record<string, unknown>,
    options: Record<string, unknown>,
  ): Promise<{
    results: IPropertyDoc[];
    page: number;
    limit: number;
    totalPages: number;
    totalResults: number;
  }>;
}

export type NewCreatedProperty = Omit<IProperty, 'createdAt' | 'updatedAt'>;

export type UpdatePropertyBody = Partial<
  Omit<IProperty, 'createdAt' | 'updatedAt'>
>;

export type getPropertyLocationCountResponse = {
  area: string;
  count: number;
}[];

export type propertyLocationAggregateResponse = {
  _id: {
    locality: string;
  };
  count: number;
};

export enum PropertyType {
  sell = 'sell',
  rent = 'rent',
  lease = 'lease',
  preLease = 'preLease',
}

export const PropertyAgeOptions = [
  {
    label: 'More than 5 years',
    value: 'lt:5',
  },
  {
    label: 'More than 2 years',
    value: 'gt:2',
  },
];

export const avgPriceOptions = [
  {
    value: 'under_50L',
    label: 'Under 50L',
  },
  {
    value: '50L_1Cr',
    label: '50L to 1Cr',
  },
  {
    value: 'above_1Cr',
    label: 'Above 1Cr',
  },
];

export const SqFtOptions = [
  {
    value: '100-150',
    label: '100 to 150 sq.ft.',
  },
  {
    value: '350-450',
    label: '350 to 450 sq.ft.',
  },
  {
    value: '750',
    label: 'Above 750 sq.ft.',
  },
];