/**
 * GEO Intelligence Models
 *
 * Persistence layer for the AI Discoverability (GEO) intelligence platform:
 * - Audit snapshots (historical performance / trends / automated audits)
 * - Per-AI-platform tracking metrics
 * - Citation opportunities detected by the Opportunity Finder
 * - Content recommendations produced by the Recommendation Engine
 * - Citation simulator run history
 * - Automated audit scheduling settings
 *
 * These are GEO-module models. All scores stored here are DERIVED estimates
 * computed from the company's own module data (labelled as such in the UI) —
 * no AI platform publishes citation data, so nothing here is a live measurement.
 */

import mongoose, { Schema, Document } from 'mongoose';

// ============================================
// TYPES
// ============================================

export type GeoScoreKey =
  | 'entityCompleteness'
  | 'trustSignals'
  | 'contentCoverage'
  | 'brandAuthority'
  | 'geoHealth'
  | 'aiReadiness'
  | 'aiVisibility'
  | 'citation';

export type GeoAuditType = 'manual' | 'scheduled' | 'baseline';
export type GeoAuditFrequency = 'weekly' | 'biweekly' | 'monthly';

export type GeoOpportunityStatus = 'open' | 'planned' | 'in-progress' | 'done' | 'dismissed';
export type GeoRecommendationStatus = 'open' | 'approved' | 'ignored' | 'done';

// ============================================
// GEO AUDIT SNAPSHOT
// ============================================

export interface IGeoAuditSnapshot extends Document {
  companyId: string;
  auditType: GeoAuditType;
  scores: Partial<Record<GeoScoreKey, number>>;
  inventory: Record<string, number>;
  recommendationsCount: number;
  generatedAt: Date;
  notes?: string;
}

const GeoAuditSnapshotSchema = new Schema<IGeoAuditSnapshot>(
  {
    companyId: { type: String, required: true, index: true },
    auditType: { type: String, enum: ['manual', 'scheduled', 'baseline'], default: 'manual' },
    scores: { type: Object, default: {} },
    inventory: { type: Object, default: {} },
    recommendationsCount: { type: Number, default: 0 },
    notes: { type: String },
  },
  { timestamps: true }
);

GeoAuditSnapshotSchema.index({ companyId: 1, generatedAt: -1 });

// ============================================
// GEO PLATFORM METRIC
// ============================================

export interface IGeoPlatformMetric extends Document {
  companyId: string;
  platform: string;
  recordedAt: Date;
  visibility: number;
  citations: number;
  readiness: number;
  notes?: string;
}

const GeoPlatformMetricSchema = new Schema<IGeoPlatformMetric>(
  {
    companyId: { type: String, required: true, index: true },
    platform: { type: String, required: true, index: true },
    recordedAt: { type: Date, default: () => new Date() },
    visibility: { type: Number, min: 0, max: 100, default: 0 },
    citations: { type: Number, default: 0 },
    readiness: { type: Number, min: 0, max: 100, default: 0 },
    notes: { type: String },
  },
  { timestamps: true }
);

GeoPlatformMetricSchema.index({ companyId: 1, platform: 1, recordedAt: -1 });

// ============================================
// GEO CITATION OPPORTUNITY
// ============================================

export interface IGeoCitationOpportunity extends Document {
  companyId: string;
  sourceKey: string;
  opportunityType: string;
  title: string;
  gap: string;
  priority: 'high' | 'medium' | 'low';
  status: GeoOpportunityStatus;
  suggestedContent: string;
  createdAt: Date;
  updatedAt: Date;
}

const GeoCitationOpportunitySchema = new Schema<IGeoCitationOpportunity>(
  {
    companyId: { type: String, required: true, index: true },
    sourceKey: { type: String, required: true },
    opportunityType: { type: String, required: true },
    title: { type: String, required: true },
    gap: { type: String, default: '' },
    priority: { type: String, enum: ['high', 'medium', 'low'], default: 'medium' },
    status: {
      type: String,
      enum: ['open', 'planned', 'in-progress', 'done', 'dismissed'],
      default: 'open',
    },
    suggestedContent: { type: String, default: '' },
  },
  { timestamps: true }
);

GeoCitationOpportunitySchema.index({ companyId: 1, sourceKey: 1 }, { unique: true });
GeoCitationOpportunitySchema.index({ companyId: 1, status: 1 });

// ============================================
// GEO RECOMMENDATION
// ============================================

export interface IGeoRecommendation extends Document {
  companyId: string;
  sourceKey: string;
  source:
    | 'competitor-gap'
    | 'citation-gap'
    | 'entity-gap'
    | 'knowledge-graph'
    | 'search-intent'
    | 'missing-citation'
    | 'trend';
  title: string;
  reasoning: string;
  priority: 'high' | 'medium' | 'low';
  status: GeoRecommendationStatus;
  targetModule?: string;
  createdAt: Date;
  updatedAt: Date;
}

const GeoRecommendationSchema = new Schema<IGeoRecommendation>(
  {
    companyId: { type: String, required: true, index: true },
    sourceKey: { type: String, required: true },
    source: { type: String, enum: ['competitor-gap', 'citation-gap', 'entity-gap', 'knowledge-graph', 'search-intent', 'missing-citation', 'trend'], required: true },
    title: { type: String, required: true },
    reasoning: { type: String, default: '' },
    priority: { type: String, enum: ['high', 'medium', 'low'], default: 'medium' },
    status: { type: String, enum: ['open', 'approved', 'ignored', 'done'], default: 'open' },
    targetModule: { type: String, default: '' },
  },
  { timestamps: true }
);

GeoRecommendationSchema.index({ companyId: 1, sourceKey: 1 }, { unique: true });
GeoRecommendationSchema.index({ companyId: 1, status: 1 });

// ============================================
// GEO SIMULATION RUN
// ============================================

export interface IGeoSimulationRun extends Document {
  companyId: string;
  prompt: string;
  predictedCitation: number;
  visibilityProbability: number;
  weakAreas: string[];
  missingContent: string[];
  recommendedImprovements: string[];
  createdAt: Date;
}

const GeoSimulationRunSchema = new Schema<IGeoSimulationRun>(
  {
    companyId: { type: String, required: true, index: true },
    prompt: { type: String, required: true },
    predictedCitation: { type: Number, default: 0 },
    visibilityProbability: { type: Number, default: 0 },
    weakAreas: { type: [String], default: [] },
    missingContent: { type: [String], default: [] },
    recommendedImprovements: { type: [String], default: [] },
  },
  { timestamps: true }
);

GeoSimulationRunSchema.index({ companyId: 1, createdAt: -1 });

// ============================================
// GEO AUDIT SETTINGS
// ============================================

export interface IGeoAuditSettings extends Document {
  companyId: string;
  autoAuditEnabled: boolean;
  frequency: GeoAuditFrequency;
  lastAuditAt?: Date;
  nextAuditAt?: Date;
  createdAt: Date;
  updatedAt: Date;
}

const GeoAuditSettingsSchema = new Schema<IGeoAuditSettings>(
  {
    companyId: { type: String, required: true, unique: true, index: true },
    autoAuditEnabled: { type: Boolean, default: false },
    frequency: { type: String, enum: ['weekly', 'biweekly', 'monthly'], default: 'weekly' },
    lastAuditAt: { type: Date },
    nextAuditAt: { type: Date },
  },
  { timestamps: true }
);

// ============================================
// EXPORTS
// ============================================

export const GeoAuditSnapshot = mongoose.models.GeoAuditSnapshot || mongoose.model<IGeoAuditSnapshot>('GeoAuditSnapshot', GeoAuditSnapshotSchema);
export const GeoPlatformMetric = mongoose.models.GeoPlatformMetric || mongoose.model<IGeoPlatformMetric>('GeoPlatformMetric', GeoPlatformMetricSchema);
export const GeoCitationOpportunity = mongoose.models.GeoCitationOpportunity || mongoose.model<IGeoCitationOpportunity>('GeoCitationOpportunity', GeoCitationOpportunitySchema);
export const GeoRecommendation = mongoose.models.GeoRecommendation || mongoose.model<IGeoRecommendation>('GeoRecommendation', GeoRecommendationSchema);
export const GeoSimulationRun = mongoose.models.GeoSimulationRun || mongoose.model<IGeoSimulationRun>('GeoSimulationRun', GeoSimulationRunSchema);
export const GeoAuditSettings = mongoose.models.GeoAuditSettings || mongoose.model<IGeoAuditSettings>('GeoAuditSettings', GeoAuditSettingsSchema);
