import { logger } from '../utils/logger';
import ReturnRateDatabaseService, { SKUReturnMetrics, ReturnAnalysis } from './ReturnRateDatabaseService';

export interface ImprovementRequest {
  tenant_id: string;
  shop_id: string;
  task_id?: string;
  trace_id: string;
  product_id: string;
  sku_id: string;
  platform: string;
}

export interface ImprovementSuggestion {
  id: string;
  tenant_id: string;
  product_id: string;
  sku_id: string;
  platform: string;
  improvement_type: 'PRICE' | 'DESCRIPTION' | 'IMAGES' | 'QUALITY' | 'PACKAGING' | 'SHIPPING' | 'CUSTOMER_SERVICE' | 'REVIEW_RESPONSE';
  priority: 'HIGH' | 'MEDIUM' | 'LOW';
  title: string;
  description: string;
  expected_impact: string;
  estimated_cost?: number;
  estimated_roi?: number;
  implementation_difficulty: 'EASY' | 'MEDIUM' | 'HARD';
  implementation_steps: string[];
  competitor_benchmark?: string;
  generated_at: Date;
  status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'DISMISSED';
  completed_at?: Date;
}

export interface BatchImprovementResult {
  success: boolean;
  processed: number;
  suggestions_generated: number;
  results: ImprovementSuggestion[];
}

export interface CategoryAnalysis {
  category: string;
  avg_return_rate: number;
  top_issues: string[];
  recommendations: string[];
}

export default class ImprovementSuggestionService {
  private static instance: ImprovementSuggestionService;

  static getInstance(): ImprovementSuggestionService {
    if (!ImprovementSuggestionService.instance) {
      ImprovementSuggestionService.instance = new ImprovementSuggestionService();
    }
    return ImprovementSuggestionService.instance;
  }

  async generateSuggestions(request: ImprovementRequest): Promise<{ success: boolean; suggestions?: ImprovementSuggestion[]; error?: string }> {
    try {
      logger.info(`[ImprovementSuggestionService] Generating improvement suggestions: productId=${request.product_id}, traceId=${request.trace_id}`);

      const metrics = await db('cf_sku_return_metrics')
        .where({ 
          tenant_id: request.tenant_id, 
          product_id: request.product_id,
          sku_id: request.sku_id
        })
        .first() as SKUReturnMetrics | undefined;

      if (!metrics) {
        return { success: false, error: 'No return metrics found for this SKU' };
      }

      const suggestions: ImprovementSuggestion[] = [];
      const returnReasons = metrics.return_by_reason ? JSON.parse(metrics.return_by_reason as string) : {};
      const returnRate = parseFloat(metrics.return_rate as unknown as string) || 0;

      if (returnReasons['Quality Issues'] || returnReasons['Defective']) {
        suggestions.push(this.createSuggestion(
          request,
          'QUALITY',
          'HIGH',
          'Quality Improvement Needed',
          `Return rate due to quality issues: ${returnReasons['Quality Issues'] || 0}. Consider improving product quality or sourcing from better suppliers.`,
          `Expected reduction: 15-25% in return rate`,
          'MEDIUM',
          ['Audit current supplier quality', 'Request quality certifications', 'Implement quality checks before shipping', 'Consider alternative suppliers']
        ));
      }

      if (returnReasons['Not as Described'] || returnReasons['Wrong Item']) {
        suggestions.push(this.createSuggestion(
          request,
          'DESCRIPTION',
          'HIGH',
          'Product Description Enhancement',
          `Return rate due to description issues: ${returnReasons['Not as Described'] || 0}. Improve product description accuracy.`,
          `Expected reduction: 10-20% in return rate`,
          'EASY',
          ['Update product title with accurate keywords', 'Add detailed specifications', 'Include measurement guides', 'Add comparison charts']
        ));
      }

      if (returnReasons['Photos Not Accurate'] || returnReasons['Color Different']) {
        suggestions.push(this.createSuggestion(
          request,
          'IMAGES',
          'HIGH',
          'Image Enhancement Required',
          `Return rate due to image issues: ${returnReasons['Photos Not Accurate'] || 0}. Improve product photography.`,
          `Expected reduction: 12-18% in return rate`,
          'EASY',
          ['Use professional photography', 'Add multiple angle views', 'Include scale reference', 'Show product in use', 'Add close-up detail shots']
        ));
      }

      if (returnReasons['Too Large'] || returnReasons['Too Small'] || returnReasons['Size Not Fit']) {
        suggestions.push(this.createSuggestion(
          request,
          'DESCRIPTION',
          'MEDIUM',
          'Size Guide Enhancement',
          'Returns due to size issues detected. Add comprehensive size guides.',
          `Expected reduction: 8-15% in return rate`,
          'EASY',
          ['Add detailed size chart', 'Include measurement instructions', 'Add fit recommendation', 'Show model measurements']
        ));
      }

      if (returnReasons['Packaging Damaged'] || returnReasons['Packaging Poor']) {
        suggestions.push(this.createSuggestion(
          request,
          'PACKAGING',
          'MEDIUM',
          'Packaging Improvement',
          'Returns due to packaging issues. Consider upgrading packaging materials.',
          `Expected reduction: 5-10% in return rate`,
          'EASY',
          ['Use stronger packaging materials', 'Add cushioning', 'Improve sealing', 'Use tamper-evident packaging']
        ));
      }

      if (returnReasons['Shipping Damaged'] || returnReasons['Delivery Delay']) {
        suggestions.push(this.createSuggestion(
          request,
          'SHIPPING',
          'MEDIUM',
          'Shipping Optimization',
          'Returns due to shipping issues. Optimize shipping method and packaging.',
          `Expected reduction: 8-12% in return rate`,
          'MEDIUM',
          ['Evaluate shipping partners', 'Add insurance for high-value items', 'Optimize packaging for shipping', 'Consider expedited options']
        ));
      }

      if (returnReasons['Customer Service'] || returnReasons['No Response']) {
        suggestions.push(this.createSuggestion(
          request,
          'CUSTOMER_SERVICE',
          'MEDIUM',
          'Customer Service Enhancement',
          'Returns due to customer service issues. Improve pre-sales support.',
          `Expected reduction: 5-10% in return rate`,
          'EASY',
          ['Add FAQ section', 'Implement live chat', 'Response time optimization', 'Add product video guides']
        ));
      }

      if (returnRate > 30) {
        suggestions.push(this.createSuggestion(
          request,
          'PRICE',
          'HIGH',
          'Price Review Needed',
          `High overall return rate (${returnRate}%). Consider price adjustment to match customer expectations.`,
          `Potential revenue improvement: 10-20%`,
          'MEDIUM',
          ['Analyze competitor pricing', 'Evaluate value proposition', 'Consider bundle pricing', 'Review discount strategies']
        ));
      }

      if (returnReasons['Changed Mind'] || returnReasons['No Reason']) {
        suggestions.push(this.createSuggestion(
          request,
          'CUSTOMER_SERVICE',
          'LOW',
          'Post-Purchase Engagement',
          'Returns due to buyer regret. Improve post-purchase communication.',
          `Expected reduction: 5-8% in return rate`,
          'EASY',
          ['Send order confirmation emails', 'Add shipping updates', 'Include thank you notes', 'Offer loyalty discounts']
        ));
      }

      for (const suggestion of suggestions) {
        await db('cf_improvement_suggestion').insert(suggestion);
      }

      logger.info(`[ImprovementSuggestionService] Generated ${suggestions.length} suggestions for product ${request.product_id}, traceId=${request.trace_id}`);
      return { success: true, suggestions };
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to generate suggestions: ${error.message}, traceId=${request.trace_id}`);
      return { success: false, error: error.message };
    }
  }

  private createSuggestion(
    request: ImprovementRequest,
    type: ImprovementSuggestion['improvement_type'],
    priority: ImprovementSuggestion['priority'],
    title: string,
    description: string,
    expectedImpact: string,
    difficulty: ImprovementSuggestion['implementation_difficulty'],
    steps: string[]
  ): ImprovementSuggestion {
    return {
      id: uuidv4(),
      tenant_id: request.tenant_id,
      product_id: request.product_id,
      sku_id: request.sku_id,
      platform: request.platform,
      improvement_type: type,
      priority,
      title,
      description,
      expected_impact: expectedImpact,
      implementation_difficulty: difficulty,
      implementation_steps: steps,
      generated_at: new Date(),
      status: 'PENDING'
    };
  }

  async generateSuggestionsForHighRisk(tenantId: string, shopId?: string): Promise<BatchImprovementResult> {
    try {
      logger.info(`[ImprovementSuggestionService] Generating suggestions for high risk SKUs: tenantId=${tenantId}`);

      const highRiskSKUs = await ReturnRateDatabaseService.getHighRiskSKUs(tenantId, shopId);

      let processed = 0;
      let suggestionsGenerated = 0;
      const results: ImprovementSuggestion[] = [];

      for (const sku of highRiskSKUs) {
        const result = await this.generateSuggestions({
          tenant_id: tenantId,
          shop_id: sku.shop_id,
          product_id: sku.product_id,
          sku_id: sku.sku_id,
          platform: sku.platform,
          trace_id: ''
        });

        if (result.success && result.suggestions) {
          suggestionsGenerated += result.suggestions.length;
          results.push(...result.suggestions);
        }
        processed++;
      }

      logger.info(`[ImprovementSuggestionService] Batch suggestion generation completed: processed=${processed}, generated=${suggestionsGenerated}`);
      return { success: true, processed, suggestions_generated: suggestionsGenerated, results };
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to generate batch suggestions: ${error.message}`);
      return { success: false, processed: 0, suggestions_generated: 0, results: [] };
    }
  }

  async getSuggestions(tenantId: string, filter?: {
    product_id?: string;
    sku_id?: string;
    platform?: string;
    improvement_type?: string;
    priority?: string;
    status?: string;
  }): Promise<ImprovementSuggestion[]> {
    try {
      let query = db('cf_improvement_suggestion').where({ tenant_id: tenantId });

      if (filter?.product_id) query = query.where({ product_id: filter.product_id });
      if (filter?.sku_id) query = query.where({ sku_id: filter.sku_id });
      if (filter?.platform) query = query.where({ platform: filter.platform });
      if (filter?.improvement_type) query = query.where({ improvement_type: filter.improvement_type });
      if (filter?.priority) query = query.where({ priority: filter.priority });
      if (filter?.status) query = query.where({ status: filter.status });

      return await query.orderBy('generated_at', 'desc');
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to get suggestions: ${error.message}`);
      return [];
    }
  }

  async updateSuggestionStatus(id: string, status: ImprovementSuggestion['status']): Promise<{ success: boolean; error?: string }> {
    try {
      const updateData: any = { status };
      if (status === 'COMPLETED') {
        updateData.completed_at = new Date();
      }

      await db('cf_improvement_suggestion').where({ id }).update(updateData);
      return { success: true };
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to update suggestion status: ${error.message}`);
      return { success: false, error: error.message };
    }
  }

  async dismissSuggestion(id: string, reason: string): Promise<{ success: boolean; error?: string }> {
    try {
      await db('cf_improvement_suggestion')
        .where({ id })
        .update({ status: 'DISMISSED', description: db.raw('CONCAT(description, ?, ?)', [`\n\nDismissed: ${reason}`, '']) });
      return { success: true };
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to dismiss suggestion: ${error.message}`);
      return { success: false, error: error.message };
    }
  }

  async getImprovementAnalytics(tenantId: string): Promise<{
    total_suggestions: number;
    by_type: Record<string, number>;
    by_priority: Record<string, number>;
    by_status: Record<string, number>;
    completion_rate: number;
    avg_roi?: number;
  }> {
    try {
      const allSuggestions = await db('cf_improvement_suggestion').where({ tenant_id: tenantId });

      const byType: Record<string, number> = {};
      const byPriority: Record<string, number> = {};
      const byStatus: Record<string, number> = {};

      for (const s of allSuggestions) {
        byType[s.improvement_type] = (byType[s.improvement_type] || 0) + 1;
        byPriority[s.priority] = (byPriority[s.priority] || 0) + 1;
        byStatus[s.status] = (byStatus[s.status] || 0) + 1;
      }

      const completed = allSuggestions.filter(s => s.status === 'COMPLETED').length;
      const completionRate = allSuggestions.length > 0 ? (completed / allSuggestions.length) * 100 : 0;

      return {
        total_suggestions: allSuggestions.length,
        by_type: byType,
        by_priority: byPriority,
        by_status: byStatus,
        completion_rate: completionRate
      };
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to get improvement analytics: ${error.message}`);
      return {
        total_suggestions: 0,
        by_type: {},
        by_priority: {},
        by_status: {},
        completion_rate: 0
      };
    }
  }

  async getCategoryAnalysis(tenantId: string): Promise<CategoryAnalysis[]> {
    try {
      const skuMetrics = await db('cf_sku_return_metrics')
        .where({ tenant_id: tenantId })
        .where('is_high_risk', true);

      const categoryMap: Record<string, { total: number; count: number; issues: Record<string, number> }> = {};

      for (const sku of skuMetrics) {
        const product = await db('cf_product').where({ id: sku.product_id }).first();
        const category = product?.category || 'Unknown';

        if (!categoryMap[category]) {
          categoryMap[category] = { total: 0, count: 0, issues: {} };
        }

        categoryMap[category].total += parseFloat(sku.return_rate as string) || 0;
        categoryMap[category].count++;

        const reasons = sku.return_by_reason ? JSON.parse(sku.return_by_reason as string) : {};
        for (const [reason, count] of Object.entries(reasons)) {
          categoryMap[category].issues[reason] = (categoryMap[category].issues[reason] || 0) + (count as number);
        }
      }

      const analyses: CategoryAnalysis[] = [];
      for (const [category, data] of Object.entries(categoryMap)) {
        const avgReturnRate = data.count > 0 ? data.total / data.count : 0;
        const topIssues = Object.entries(data.issues)
          .sort((a, b) => (b[1] as number) - (a[1] as number))
          .slice(0, 3)
          .map(([issue]) => issue);

        const recommendations = this.generateCategoryRecommendations(topIssues);

        analyses.push({
          category,
          avg_return_rate: avgReturnRate,
          top_issues: topIssues,
          recommendations
        });
      }

      return analyses.sort((a, b) => b.avg_return_rate - a.avg_return_rate);
    } catch (error: any) {
      logger.error(`[ImprovementSuggestionService] Failed to get category analysis: ${error.message}`);
      return [];
    }
  }

  private generateCategoryRecommendations(topIssues: string[]): string[] {
    const recommendations: string[] = [];
    const issueSet = new Set(topIssues.map(i => i.toLowerCase()));

    if (issueSet.has('quality issues') || issueSet.has('defective')) {
      recommendations.push('Implement supplier quality audit program');
      recommendations.push('Add pre-shipment inspection');
    }

    if (issueSet.has('not as described') || issueSet.has('wrong item')) {
      recommendations.push('Standardize product specifications');
      recommendations.push('Create detailed product templates');
    }

    if (issueSet.has('photos not accurate') || issueSet.has('color different')) {
      recommendations.push('Invest in professional product photography');
      recommendations.push('Add 360-degree product views');
    }

    if (issueSet.has('size not fit') || issueSet.has('too large') || issueSet.has('too small')) {
      recommendations.push('Develop comprehensive size guides');
      recommendations.push('Add fit recommendation algorithm');
    }

    return recommendations;
  }
}

import db from '../config/database';
import { v4 as uuidv4 } from 'uuid';
