/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Predictive Analytics Repository - Data access layer
 */

import { getRegisteredContainer } from '@bytelyst/cosmos';
import type {
  UserChurnPredictionDoc,
  ProductHealthScoreDoc,
  RetentionCampaignDoc,
  UserFeatureVectorDoc,
  FeatureDefinition,
  ModelPerformanceDoc,
} from './types.js';

export class PredictiveAnalyticsRepository {
  // ==================== Churn Predictions ====================

  async saveChurnPrediction(doc: UserChurnPredictionDoc): Promise<UserChurnPredictionDoc> {
    const container = getRegisteredContainer('churn_predictions');
    await container.items.create(doc);
    return doc;
  }

  async getChurnPrediction(
    userId: string,
    productId: string,
    horizon: number = 30
  ): Promise<UserChurnPredictionDoc | null> {
    const container = getRegisteredContainer('churn_predictions');
    const query = {
      query:
        'SELECT * FROM c WHERE c.userId = @userId AND c.productId = @productId AND c.predictionHorizon = @horizon ORDER BY c.predictionTimestamp DESC OFFSET 0 LIMIT 1',
      parameters: [
        { name: '@userId', value: userId },
        { name: '@productId', value: productId },
        { name: '@horizon', value: horizon },
      ],
    };
    const { resources } = await container.items.query<UserChurnPredictionDoc>(query).fetchAll();
    return resources[0] || null;
  }

  async getAtRiskUsers(
    productId: string,
    segment?: string,
    limit: number = 50,
    offset: number = 0
  ): Promise<UserChurnPredictionDoc[]> {
    const container = getRegisteredContainer('churn_predictions');
    let queryStr = 'SELECT * FROM c WHERE c.productId = @productId';
    const parameters: Array<{ name: string; value: string | number }> = [
      { name: '@productId', value: productId },
    ];

    if (segment) {
      queryStr += ' AND c.riskSegment = @segment';
      parameters.push({ name: '@segment', value: segment });
    }

    queryStr += ' ORDER BY c.churnProbability DESC OFFSET @offset LIMIT @limit';
    parameters.push({ name: '@offset', value: offset });
    parameters.push({ name: '@limit', value: limit });

    const { resources } = await container.items
      .query<UserChurnPredictionDoc>({
        query: queryStr,
        parameters,
      })
      .fetchAll();
    return resources;
  }

  async getUserRiskProfile(userId: string, productId: string): Promise<UserChurnPredictionDoc[]> {
    const container = getRegisteredContainer('churn_predictions');
    const query = {
      query:
        'SELECT * FROM c WHERE c.userId = @userId AND c.productId = @productId ORDER BY c.predictionTimestamp DESC',
      parameters: [
        { name: '@userId', value: userId },
        { name: '@productId', value: productId },
      ],
    };
    const { resources } = await container.items.query<UserChurnPredictionDoc>(query).fetchAll();
    return resources;
  }

  // ==================== Health Scores ====================

  async saveHealthScore(doc: ProductHealthScoreDoc): Promise<ProductHealthScoreDoc> {
    const container = getRegisteredContainer('product_health');
    await container.items.create(doc);
    return doc;
  }

  async getHealthScore(productId: string, date: string): Promise<ProductHealthScoreDoc | null> {
    const container = getRegisteredContainer('product_health');
    try {
      const { resource } = await container
        .item(`${productId}:${date}`, productId)
        .read<ProductHealthScoreDoc>();
      return resource || null;
    } catch {
      return null;
    }
  }

  async getHealthHistory(productId: string, days: number = 30): Promise<ProductHealthScoreDoc[]> {
    const container = getRegisteredContainer('product_health');
    const cutoff = new Date();
    cutoff.setDate(cutoff.getDate() - days);

    const query = {
      query:
        'SELECT * FROM c WHERE c.productId = @productId AND c.date >= @cutoff ORDER BY c.date DESC',
      parameters: [
        { name: '@productId', value: productId },
        { name: '@cutoff', value: cutoff.toISOString().split('T')[0] },
      ],
    };
    const { resources } = await container.items.query<ProductHealthScoreDoc>(query).fetchAll();
    return resources;
  }

  async getAllProductHealthScores(): Promise<ProductHealthScoreDoc[]> {
    const container = getRegisteredContainer('product_health');
    const today = new Date().toISOString().split('T')[0];

    const query = {
      query: 'SELECT * FROM c WHERE c.date = @today',
      parameters: [{ name: '@today', value: today }],
    };
    const { resources } = await container.items.query<ProductHealthScoreDoc>(query).fetchAll();
    return resources;
  }

  // ==================== Campaigns ====================

  async getCampaign(campaignId: string): Promise<RetentionCampaignDoc | null> {
    const container = getRegisteredContainer('retention_campaigns');
    try {
      const { resource } = await container
        .item(campaignId, campaignId)
        .read<RetentionCampaignDoc>();
      return resource || null;
    } catch {
      return null;
    }
  }

  async listCampaigns(productId?: string, status?: string): Promise<RetentionCampaignDoc[]> {
    const container = getRegisteredContainer('retention_campaigns');
    let queryStr = 'SELECT * FROM c WHERE 1=1';
    const parameters: Array<{ name: string; value: string }> = [];

    if (productId) {
      queryStr += ' AND c.productId = @productId';
      parameters.push({ name: '@productId', value: productId });
    }

    if (status) {
      queryStr += ' AND c.status = @status';
      parameters.push({ name: '@status', value: status });
    }

    queryStr += ' ORDER BY c.createdAt DESC';

    const { resources } = await container.items
      .query<RetentionCampaignDoc>({
        query: queryStr,
        parameters,
      })
      .fetchAll();
    return resources;
  }

  async updateCampaign(
    campaignId: string,
    updates: Partial<RetentionCampaignDoc>
  ): Promise<RetentionCampaignDoc | null> {
    const container = getRegisteredContainer('retention_campaigns');

    try {
      const { resource: doc } = await container.item(campaignId).read<RetentionCampaignDoc>();
      if (!doc) return null;

      const updated = { ...doc, ...updates, updatedAt: new Date().toISOString() };
      await container.item(campaignId).replace(updated);
      return updated;
    } catch {
      return null;
    }
  }

  async deleteCampaign(campaignId: string): Promise<boolean> {
    const container = getRegisteredContainer('retention_campaigns');
    try {
      await container.item(campaignId).delete();
      return true;
    } catch {
      return false;
    }
  }

  // ==================== Feature Definitions ====================

  async saveFeatureDefinition(doc: FeatureDefinition): Promise<FeatureDefinition> {
    const container = getRegisteredContainer('feature_definitions');
    await container.items.create(doc);
    return doc;
  }

  async getFeatureDefinitions(productId: string): Promise<FeatureDefinition[]> {
    const container = getRegisteredContainer('feature_definitions');
    const query = {
      query: 'SELECT * FROM c WHERE c.productId = @productId',
      parameters: [{ name: '@productId', value: productId }],
    };
    const { resources } = await container.items.query<FeatureDefinition>(query).fetchAll();
    return resources;
  }

  // ==================== Model Performance ====================

  async saveModelPerformance(doc: ModelPerformanceDoc): Promise<ModelPerformanceDoc> {
    const container = getRegisteredContainer('model_performance');
    await container.items.create(doc);
    return doc;
  }

  async getLatestModelPerformance(): Promise<ModelPerformanceDoc | null> {
    const container = getRegisteredContainer('model_performance');
    const query = {
      query: 'SELECT * FROM c WHERE c.isActive = true ORDER BY c.createdAt DESC OFFSET 0 LIMIT 1',
    };
    const { resources } = await container.items.query<ModelPerformanceDoc>(query).fetchAll();
    return resources[0] || null;
  }

  async getModelPerformanceHistory(limit: number = 10): Promise<ModelPerformanceDoc[]> {
    const container = getRegisteredContainer('model_performance');
    const query = {
      query: 'SELECT * FROM c ORDER BY c.createdAt DESC OFFSET 0 LIMIT @limit',
      parameters: [{ name: '@limit', value: limit }],
    };
    const { resources } = await container.items.query<ModelPerformanceDoc>(query).fetchAll();
    return resources;
  }
}

export const predictiveAnalyticsRepo = new PredictiveAnalyticsRepository();
