import { logger } from '../utils/logger';
import BlacklistDatabaseService, { BlacklistRecord, BlacklistFilter, BlacklistStatistics } from './BlacklistDatabaseService';

export interface AddToBlacklistRequest {
  tenant_id: string;
  shop_id: string;
  task_id?: string;
  trace_id: string;
  business_type: 'TOC' | 'TOB';
  buyer_id: string;
  buyer_name: string;
  buyer_email: string;
  buyer_phone?: string;
  platform: string;
  platform_buyer_id: string;
  blacklist_reason: string;
  blacklist_type: 'FRAUD' | 'CHARGEBACK' | 'ABUSE' | 'OTHER';
  risk_score: number;
  blacklist_date?: Date;
  expiry_date?: Date;
  evidence?: string;
  created_by: string;
}

export interface UpdateBlacklistRequest {
  id: string;
  trace_id: string;
  buyer_name?: string;
  buyer_email?: string;
  buyer_phone?: string;
  blacklist_reason?: string;
  blacklist_type?: 'FRAUD' | 'CHARGEBACK' | 'ABUSE' | 'OTHER';
  risk_score?: number;
  expiry_date?: Date;
  status?: 'ACTIVE' | 'INACTIVE' | 'EXPIRED';
  evidence?: string;
  updated_by: string;
}

export interface BlacklistResponse {
  success: boolean;
  message?: string;
  data?: BlacklistRecord;
  error?: string;
}

export interface BlacklistListResponse {
  success: boolean;
  records: BlacklistRecord[];
  total: number;
  message?: string;
  error?: string;
}

export interface BlacklistCheckResponse {
  is_blacklisted: boolean;
  record?: BlacklistRecord;
  reasons?: string[];
  risk_score?: number;
}

export default class BlacklistService {
  private static instance: BlacklistService;

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

  async addToBlacklist(request: AddToBlacklistRequest): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Adding buyer to blacklist: email=${request.buyer_email}, platform=${request.platform}, traceId=${request.trace_id}`);

      // 检查是否已经在黑名单中
      const existingRecord = await BlacklistDatabaseService.getBlacklistRecordByPlatform(
        request.platform,
        request.platform_buyer_id,
        request.tenant_id
      );

      if (existingRecord) {
        logger.info(`[BlacklistService] Buyer already in blacklist: id=${existingRecord.id}, traceId=${request.trace_id}`);
        return {
          success: false,
          message: 'Buyer already in blacklist',
          data: existingRecord
        };
      }

      const record = await BlacklistDatabaseService.createBlacklistRecord({
        ...request,
        blacklist_date: request.blacklist_date || new Date(),
        status: 'ACTIVE'
      });

      logger.info(`[BlacklistService] Buyer added to blacklist successfully: id=${record.id}, traceId=${request.trace_id}`);
      return {
        success: true,
        message: 'Buyer added to blacklist successfully',
        data: record
      };
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to add buyer to blacklist: ${error.message}, traceId=${request.trace_id}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async removeFromBlacklist(id: string, trace_id: string, removed_by: string): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Removing buyer from blacklist: id=${id}, traceId=${trace_id}`);

      const record = await BlacklistDatabaseService.getBlacklistRecordById(id);
      if (!record) {
        return {
          success: false,
          error: 'Blacklist record not found'
        };
      }

      const result = await BlacklistDatabaseService.updateBlacklistRecord(id, {
        status: 'INACTIVE',
        trace_id
      });

      if (result) {
        logger.info(`[BlacklistService] Buyer removed from blacklist: id=${id}, traceId=${trace_id}`);
        return {
          success: true,
          message: 'Buyer removed from blacklist successfully'
        };
      } else {
        return {
          success: false,
          error: 'Failed to remove buyer from blacklist'
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to remove buyer from blacklist: ${error.message}, traceId=${trace_id}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async updateBlacklist(request: UpdateBlacklistRequest): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Updating blacklist record: id=${request.id}, traceId=${request.trace_id}`);

      const record = await BlacklistDatabaseService.getBlacklistRecordById(request.id);
      if (!record) {
        return {
          success: false,
          error: 'Blacklist record not found'
        };
      }

      const updates: Partial<BlacklistRecord> = {
        trace_id: request.trace_id
      };

      if (request.buyer_name !== undefined) updates.buyer_name = request.buyer_name;
      if (request.buyer_email !== undefined) updates.buyer_email = request.buyer_email;
      if (request.buyer_phone !== undefined) updates.buyer_phone = request.buyer_phone;
      if (request.blacklist_reason !== undefined) updates.blacklist_reason = request.blacklist_reason;
      if (request.blacklist_type !== undefined) updates.blacklist_type = request.blacklist_type;
      if (request.risk_score !== undefined) updates.risk_score = request.risk_score;
      if (request.expiry_date !== undefined) updates.expiry_date = request.expiry_date;
      if (request.status !== undefined) updates.status = request.status;
      if (request.evidence !== undefined) updates.evidence = request.evidence;

      const result = await BlacklistDatabaseService.updateBlacklistRecord(request.id, updates);

      if (result) {
        const updatedRecord = await BlacklistDatabaseService.getBlacklistRecordById(request.id);
        logger.info(`[BlacklistService] Blacklist record updated: id=${request.id}, traceId=${request.trace_id}`);
        return {
          success: true,
          message: 'Blacklist record updated successfully',
          data: updatedRecord!
        };
      } else {
        return {
          success: false,
          error: 'Failed to update blacklist record'
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to update blacklist record: ${error.message}, traceId=${request.trace_id}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async getBlacklistRecord(id: string): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Getting blacklist record: id=${id}`);
      const record = await BlacklistDatabaseService.getBlacklistRecordById(id);
      if (record) {
        return {
          success: true,
          data: record
        };
      } else {
        return {
          success: false,
          error: 'Blacklist record not found'
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to get blacklist record: ${error.message}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async getBlacklistRecords(filter: BlacklistFilter, limit: number = 100, offset: number = 0): Promise<BlacklistListResponse> {
    try {
      logger.info(`[BlacklistService] Getting blacklist records: limit=${limit}, offset=${offset}`);
      const { records, total } = await BlacklistDatabaseService.getBlacklistRecords(filter, limit, offset);
      return {
        success: true,
        records,
        total
      };
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to get blacklist records: ${error.message}`);
      return {
        success: false,
        records: [],
        total: 0,
        error: error.message
      };
    }
  }

  async checkBlacklist(platform: string, platformBuyerId: string, tenantId?: string): Promise<BlacklistCheckResponse> {
    try {
      logger.info(`[BlacklistService] Checking blacklist: platform=${platform}, buyerId=${platformBuyerId}`);
      const record = await BlacklistDatabaseService.getBlacklistRecordByPlatform(platform, platformBuyerId, tenantId);
      
      if (record && record.status === 'ACTIVE') {
        const reasons = await BlacklistDatabaseService.getBlacklistReasons(platform, platformBuyerId, tenantId);
        return {
          is_blacklisted: true,
          record,
          reasons,
          risk_score: record.risk_score
        };
      } else {
        return {
          is_blacklisted: false
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to check blacklist: ${error.message}`);
      return {
        is_blacklisted: false
      };
    }
  }

  async getBlacklistStatistics(tenantId?: string): Promise<BlacklistStatistics> {
    try {
      logger.info(`[BlacklistService] Getting blacklist statistics: tenantId=${tenantId}`);
      return await BlacklistDatabaseService.getBlacklistStatistics(tenantId);
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to get blacklist statistics: ${error.message}`);
      return {
        total_count: 0,
        active_count: 0,
        inactive_count: 0,
        expired_count: 0,
        by_type: {},
        by_platform: {},
        risk_distribution: {
          low: 0,
          medium: 0,
          high: 0
        },
        recent_additions: 0
      };
    }
  }

  async activateBlacklistRecord(id: string, trace_id: string): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Activating blacklist record: id=${id}, traceId=${trace_id}`);
      const result = await BlacklistDatabaseService.updateBlacklistRecord(id, {
        status: 'ACTIVE',
        trace_id
      });

      if (result) {
        const record = await BlacklistDatabaseService.getBlacklistRecordById(id);
        return {
          success: true,
          message: 'Blacklist record activated successfully',
          data: record!
        };
      } else {
        return {
          success: false,
          error: 'Failed to activate blacklist record'
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to activate blacklist record: ${error.message}, traceId=${trace_id}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async deactivateBlacklistRecord(id: string, trace_id: string): Promise<BlacklistResponse> {
    try {
      logger.info(`[BlacklistService] Deactivating blacklist record: id=${id}, traceId=${trace_id}`);
      const result = await BlacklistDatabaseService.updateBlacklistRecord(id, {
        status: 'INACTIVE',
        trace_id
      });

      if (result) {
        const record = await BlacklistDatabaseService.getBlacklistRecordById(id);
        return {
          success: true,
          message: 'Blacklist record deactivated successfully',
          data: record!
        };
      } else {
        return {
          success: false,
          error: 'Failed to deactivate blacklist record'
        };
      }
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to deactivate blacklist record: ${error.message}, traceId=${trace_id}`);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async searchBlacklist(query: string, tenantId?: string): Promise<BlacklistRecord[]> {
    try {
      logger.info(`[BlacklistService] Searching blacklist: query=${query}, tenantId=${tenantId}`);
      return await BlacklistDatabaseService.searchBlacklist(query, tenantId);
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to search blacklist: ${error.message}`);
      return [];
    }
  }

  async batchAddToBlacklist(records: AddToBlacklistRequest[]): Promise<{
    success: number;
    failed: number;
    errors: string[];
  }> {
    let success = 0;
    let failed = 0;
    const errors: string[] = [];

    for (const record of records) {
      try {
        const result = await this.addToBlacklist(record);
        if (result.success) {
          success++;
        } else {
          failed++;
          errors.push(`Failed to add ${record.buyer_email}: ${result.error || result.message}`);
        }
      } catch (error: any) {
        failed++;
        errors.push(`Failed to add ${record.buyer_email}: ${error.message}`);
      }
    }

    logger.info(`[BlacklistService] Batch add completed: ${success} success, ${failed} failed`);
    return { success, failed, errors };
  }

  async batchRemoveFromBlacklist(ids: string[], trace_id: string, removed_by: string): Promise<{
    success: number;
    failed: number;
    errors: string[];
  }> {
    let success = 0;
    let failed = 0;
    const errors: string[] = [];

    for (const id of ids) {
      try {
        const result = await this.removeFromBlacklist(id, trace_id, removed_by);
        if (result.success) {
          success++;
        } else {
          failed++;
          errors.push(`Failed to remove ${id}: ${result.error}`);
        }
      } catch (error: any) {
        failed++;
        errors.push(`Failed to remove ${id}: ${error.message}`);
      }
    }

    logger.info(`[BlacklistService] Batch remove completed: ${success} success, ${failed} failed`);
    return { success, failed, errors };
  }

  async cleanupExpiredRecords(): Promise<number> {
    try {
      logger.info('[BlacklistService] Cleaning up expired blacklist records');
      return await BlacklistDatabaseService.checkExpiredRecords();
    } catch (error: any) {
      logger.error(`[BlacklistService] Failed to cleanup expired records: ${error.message}`);
      return 0;
    }
  }
}
