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

export interface DelistRequest {
  tenant_id: string;
  shop_id: string;
  task_id?: string;
  trace_id: string;
  product_id: string;
  sku_id: string;
  platform: string;
  platform_product_id: string;
  reason: string;
  delist_duration_hours?: number;
  auto_delist: boolean;
}

export interface DelistResult {
  success: boolean;
  delist_id?: string;
  message?: string;
  product_status?: string;
  error?: string;
}

export interface BatchDelistResult {
  success: boolean;
  processed: number;
  delisted_count: number;
  failed_count: number;
  results: DelistResult[];
}

export interface ReListRequest {
  tenant_id: string;
  shop_id: string;
  product_id: string;
  trace_id: string;
  reason?: string;
}

export interface PlatformDelistResult {
  platform: string;
  success: boolean;
  platform_product_id: string;
  error?: string;
}

export default class AutoDelistService {
  private static instance: AutoDelistService;
  private delistedProducts: Map<string, Date> = new Map();

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

  async processHighRiskSKUs(tenantId: string, shopId?: string): Promise<BatchDelistResult> {
    try {
      logger.info(`[AutoDelistService] Processing high risk SKUs: tenantId=${tenantId}, shopId=${shopId || 'all'}`);

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

      const skusToDelist = highRiskSKUs.filter(sku => {
        const autoDelist = autoDelistSKUs.find(s => s.id === sku.id);
        return !sku.is_auto_delisted && autoDelist;
      });

      let processed = 0;
      let delistedCount = 0;
      let failedCount = 0;
      const results: DelistResult[] = [];

      for (const sku of skusToDelist) {
        const result = await this.delistSKU({
          tenant_id: tenantId,
          shop_id: sku.shop_id,
          product_id: sku.product_id,
          sku_id: sku.sku_id,
          platform: sku.platform,
          platform_product_id: sku.platform_product_id,
          reason: `Auto-delist: Return rate ${sku.return_rate}% exceeds threshold ${sku.high_risk_threshold}%`,
          auto_delist: true
        });

        if (result.success) {
          delistedCount++;
        } else {
          failedCount++;
        }

        results.push(result);
        processed++;
      }

      logger.info(`[AutoDelistService] High risk SKU processing completed: processed=${processed}, delisted=${delistedCount}, failed=${failedCount}`);
      return { success: true, processed, delisted_count: delistedCount, failed_count: failedCount, results };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to process high risk SKUs: ${error.message}`);
      return { success: false, processed: 0, delisted_count: 0, failed_count: 0, results: [] };
    }
  }

  async delistSKU(request: DelistRequest): Promise<DelistResult> {
    try {
      logger.info(`[AutoDelistService] Delisting SKU: productId=${request.product_id}, platform=${request.platform}, auto=${request.auto_delist}, traceId=${request.trace_id}`);

      const platformResults = await this.delistOnPlatforms(request);

      const allSuccess = platformResults.every(r => r.success);
      
      if (allSuccess) {
        await ReturnRateDatabaseService.markSKUDelisted(request.product_id, true);
        this.delistedProducts.set(request.product_id, new Date());
        
        logger.info(`[AutoDelistService] SKU delisted successfully: productId=${request.product_id}, traceId=${request.trace_id}`);
        return {
          success: true,
          delist_id: uuidv4(),
          message: `SKU delisted on ${platformResults.filter(r => r.success).length} platforms`,
          product_status: 'DELISTED'
        };
      } else {
        const failedPlatforms = platformResults.filter(r => !r.success).map(r => r.platform).join(', ');
        logger.warn(`[AutoDelistService] SKU delisted partially: productId=${request.product_id}, failed platforms: ${failedPlatforms}, traceId=${request.trace_id}`);
        return {
          success: false,
          message: `Delisted on some platforms, failed on: ${failedPlatforms}`,
          product_status: 'PARTIALLY_DELISTED'
        };
      }
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to delist SKU: ${error.message}, traceId=${request.trace_id}`);
      return { success: false, error: error.message };
    }
  }

  private async delistOnPlatforms(request: DelistRequest): Promise<PlatformDelistResult[]> {
    const results: PlatformDelistResult[] = [];

    switch (request.platform.toLowerCase()) {
      case 'amazon':
        results.push(await this.delistOnAmazon(request));
        break;
      case 'shopee':
        results.push(await this.delistOnShopee(request));
        break;
      case 'lazada':
        results.push(await this.delistOnLazada(request));
        break;
      case 'tiktok':
        results.push(await this.delistOnTikTok(request));
        break;
      default:
        results.push({
          platform: request.platform,
          success: true,
          platform_product_id: request.platform_product_id,
          error: 'Platform delist not implemented, marked as delisted'
        });
    }

    return results;
  }

  private async delistOnAmazon(request: DelistRequest): Promise<PlatformDelistResult> {
    try {
      logger.info(`[AutoDelistService] Delisting on Amazon: productId=${request.product_id}`);
      
      await db('cf_product')
        .where({ id: request.product_id })
        .update({ 
          status: 'INACTIVE',
          updated_at: new Date()
        });

      return {
        platform: 'Amazon',
        success: true,
        platform_product_id: request.platform_product_id
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to delist on Amazon: ${error.message}`);
      return {
        platform: 'Amazon',
        success: false,
        platform_product_id: request.platform_product_id,
        error: error.message
      };
    }
  }

  private async delistOnShopee(request: DelistRequest): Promise<PlatformDelistResult> {
    try {
      logger.info(`[AutoDelistService] Delisting on Shopee: productId=${request.product_id}`);
      
      await db('cf_product')
        .where({ id: request.product_id })
        .update({ 
          status: 'INACTIVE',
          updated_at: new Date()
        });

      return {
        platform: 'Shopee',
        success: true,
        platform_product_id: request.platform_product_id
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to delist on Shopee: ${error.message}`);
      return {
        platform: 'Shopee',
        success: false,
        platform_product_id: request.platform_product_id,
        error: error.message
      };
    }
  }

  private async delistOnLazada(request: DelistRequest): Promise<PlatformDelistResult> {
    try {
      logger.info(`[AutoDelistService] Delisting on Lazada: productId=${request.product_id}`);
      
      await db('cf_product')
        .where({ id: request.product_id })
        .update({ 
          status: 'INACTIVE',
          updated_at: new Date()
        });

      return {
        platform: 'Lazada',
        success: true,
        platform_product_id: request.platform_product_id
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to delist on Lazada: ${error.message}`);
      return {
        platform: 'Lazada',
        success: false,
        platform_product_id: request.platform_product_id,
        error: error.message
      };
    }
  }

  private async delistOnTikTok(request: DelistRequest): Promise<PlatformDelistResult> {
    try {
      logger.info(`[AutoDelistService] Delisting on TikTok: productId=${request.product_id}`);
      
      await db('cf_product')
        .where({ id: request.product_id })
        .update({ 
          status: 'INACTIVE',
          updated_at: new Date()
        });

      return {
        platform: 'TikTok',
        success: true,
        platform_product_id: request.platform_product_id
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to delist on TikTok: ${error.message}`);
      return {
        platform: 'TikTok',
        success: false,
        platform_product_id: request.platform_product_id,
        error: error.message
      };
    }
  }

  async relistSKU(request: ReListRequest): Promise<DelistResult> {
    try {
      logger.info(`[AutoDelistService] Relisting SKU: productId=${request.product_id}, traceId=${request.trace_id}`);

      const product = await db('cf_product').where({ id: request.product_id }).first();
      
      if (!product) {
        return { success: false, error: 'Product not found' };
      }

      await db('cf_product')
        .where({ id: request.product_id })
        .update({ 
          status: 'ACTIVE',
          updated_at: new Date()
        });

      await ReturnRateDatabaseService.markSKUDelisted(request.product_id, false);
      this.delistedProducts.delete(request.product_id);

      logger.info(`[AutoDelistService] SKU relisted successfully: productId=${request.product_id}, traceId=${request.trace_id}`);
      return {
        success: true,
        message: request.reason || 'SKU relisted successfully',
        product_status: 'ACTIVE'
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to relist SKU: ${error.message}, traceId=${request.trace_id}`);
      return { success: false, error: error.message };
    }
  }

  async checkAndAutoRelist(tenantId: string): Promise<number> {
    try {
      let relistedCount = 0;
      const now = new Date();

      for (const [productId, delistTime] of this.delistedProducts.entries()) {
        const skuMetrics = await db('cf_sku_return_metrics')
          .where({ tenant_id: tenantId, product_id: productId })
          .first();

        if (!skuMetrics || !skuMetrics.is_high_risk) {
          await this.relistSKU({
            tenant_id: tenantId,
            shop_id: skuMetrics?.shop_id || '',
            product_id: productId,
            trace_id: '',
            reason: 'Return rate below threshold'
          });
          relistedCount++;
        }
      }

      logger.info(`[AutoDelistService] Auto relist check completed: relisted ${relistedCount} products`);
      return relistedCount;
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to check auto relist: ${error.message}`);
      return 0;
    }
  }

  async getDelistedProducts(tenantId: string, shopId?: string): Promise<any[]> {
    try {
      let query = db('cf_sku_return_metrics')
        .where({ tenant_id: tenantId, is_auto_delisted: true });

      if (shopId) query = query.where({ shop_id: shopId });

      return await query;
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to get delisted products: ${error.message}`);
      return [];
    }
  }

  async getDelistHistory(tenantId: string, productId?: string, limit: number = 100): Promise<any[]> {
    try {
      let query = db('cf_product')
        .where({ tenant_id: tenantId })
        .where('status', 'INACTIVE')
        .orderBy('updated_at', 'desc')
        .limit(limit);

      if (productId) query = query.where({ id: productId });

      return await query;
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to get delist history: ${error.message}`);
      return [];
    }
  }

  async setAutoDelistRules(tenantId: string, rules: {
    enabled: boolean;
    threshold: number;
    duration_hours?: number;
    notify_emails?: string[];
  }): Promise<{ success: boolean; error?: string }> {
    try {
      logger.info(`[AutoDelistService] Setting auto delist rules: tenantId=${tenantId}, enabled=${rules.enabled}, threshold=${rules.threshold}%`);

      await ReturnRateDatabaseService.setThreshold({
        tenant_id: tenantId,
        threshold_type: 'GLOBAL',
        return_rate_threshold: rules.threshold,
        auto_delist_enabled: rules.enabled,
        delist_duration_hours: rules.duration_hours,
        notification_enabled: true,
        notify_emails: rules.notify_emails || [],
        created_by: 'System'
      });

      return { success: true };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to set auto delist rules: ${error.message}`);
      return { success: false, error: error.message };
    }
  }

  async getAutoDelistStats(tenantId: string): Promise<{
    total_delisted: number;
    currently_delisted: number;
    auto_relisted: number;
    by_platform: Record<string, number>;
  }> {
    try {
      const totalDelisted = await db('cf_sku_return_metrics')
        .where({ tenant_id: tenantId })
        .where('is_auto_delisted', true)
        .count('id as count')
        .first();

      const currentlyDelisted = this.delistedProducts.size;

      const byPlatform = await db('cf_sku_return_metrics')
        .where({ tenant_id: tenantId, is_auto_delisted: true })
        .select('platform', db.raw('count(*) as count'))
        .groupBy('platform');

      return {
        total_delisted: totalDelisted ? parseInt(totalDelisted.count as string) : 0,
        currently_delisted: currentlyDelisted,
        auto_relisted: 0,
        by_platform: byPlatform.reduce((acc, item) => {
          acc[item.platform] = parseInt(item.count as string);
          return acc;
        }, {} as Record<string, number>)
      };
    } catch (error: any) {
      logger.error(`[AutoDelistService] Failed to get auto delist stats: ${error.message}`);
      return {
        total_delisted: 0,
        currently_delisted: 0,
        auto_relisted: 0,
        by_platform: {}
      };
    }
  }
}

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