/**
 * WhatsApp Quick Reply Service
 * Service for managing quick reply templates
 *
 * @module WhatsApp
 */

import { Repository, FindOptionsWhere } from 'typeorm';
import { AppDataSource } from '../../../shared/database/typeorm.config';
import { QuickReply } from '../entities';
import { ServiceContext } from './account.service';

export interface CreateQuickReplyDto {
  accountId?: string;
  shortcut: string;
  title: string;
  category?: string;
  messageType?: string;
  content: string;
  mediaUrl?: string;
}

export interface UpdateQuickReplyDto {
  shortcut?: string;
  title?: string;
  category?: string;
  messageType?: string;
  content?: string;
  mediaUrl?: string;
  isActive?: boolean;
}

export interface QuickReplyFilters {
  accountId?: string;
  category?: string;
  messageType?: string;
  isActive?: boolean;
  search?: string;
}

export class QuickReplyService {
  private repository: Repository<QuickReply>;

  constructor() {
    this.repository = AppDataSource.getRepository(QuickReply);
  }

  async findAll(ctx: ServiceContext, filters?: QuickReplyFilters): Promise<QuickReply[]> {
    const where: FindOptionsWhere<QuickReply> = {
      tenantId: ctx.tenantId,
    };

    if (filters?.accountId) {
      where.accountId = filters.accountId;
    }
    if (filters?.category) {
      where.category = filters.category;
    }
    if (filters?.messageType) {
      where.messageType = filters.messageType;
    }
    if (filters?.isActive !== undefined) {
      where.isActive = filters.isActive;
    }

    return this.repository.find({
      where,
      relations: ['account'],
      order: { shortcut: 'ASC' },
    });
  }

  async findById(ctx: ServiceContext, id: string): Promise<QuickReply | null> {
    return this.repository.findOne({
      where: { id, tenantId: ctx.tenantId },
      relations: ['account'],
    });
  }

  async findByShortcut(ctx: ServiceContext, shortcut: string): Promise<QuickReply | null> {
    return this.repository.findOne({
      where: { shortcut, tenantId: ctx.tenantId },
    });
  }

  async findActive(ctx: ServiceContext, accountId?: string): Promise<QuickReply[]> {
    const where: FindOptionsWhere<QuickReply> = {
      tenantId: ctx.tenantId,
      isActive: true,
    };

    if (accountId) {
      where.accountId = accountId;
    }

    return this.repository.find({
      where,
      order: { usageCount: 'DESC' },
    });
  }

  async findByCategory(ctx: ServiceContext, category: string): Promise<QuickReply[]> {
    return this.repository.find({
      where: {
        tenantId: ctx.tenantId,
        category,
        isActive: true,
      },
      order: { shortcut: 'ASC' },
    });
  }

  async search(ctx: ServiceContext, query: string): Promise<QuickReply[]> {
    const quickReplies = await this.repository.find({
      where: { tenantId: ctx.tenantId, isActive: true },
    });

    const lowerQuery = query.toLowerCase();
    return quickReplies.filter(
      qr =>
        qr.shortcut.toLowerCase().includes(lowerQuery) ||
        qr.title.toLowerCase().includes(lowerQuery) ||
        qr.content.toLowerCase().includes(lowerQuery)
    );
  }

  async create(ctx: ServiceContext, data: CreateQuickReplyDto): Promise<QuickReply> {
    const quickReply = this.repository.create({
      ...data,
      tenantId: ctx.tenantId,
      createdBy: ctx.userId,
      isActive: true,
      messageType: data.messageType || 'text',
    });

    return this.repository.save(quickReply);
  }

  async update(ctx: ServiceContext, id: string, data: UpdateQuickReplyDto): Promise<QuickReply | null> {
    const quickReply = await this.findById(ctx, id);
    if (!quickReply) {
      return null;
    }

    Object.assign(quickReply, data);
    return this.repository.save(quickReply);
  }

  async delete(ctx: ServiceContext, id: string): Promise<boolean> {
    const result = await this.repository.delete({ id, tenantId: ctx.tenantId });
    return result.affected ? result.affected > 0 : false;
  }

  async activate(ctx: ServiceContext, id: string): Promise<QuickReply | null> {
    return this.update(ctx, id, { isActive: true });
  }

  async deactivate(ctx: ServiceContext, id: string): Promise<QuickReply | null> {
    return this.update(ctx, id, { isActive: false });
  }

  async incrementUsage(ctx: ServiceContext, id: string): Promise<void> {
    await this.repository.increment(
      { id, tenantId: ctx.tenantId },
      'usageCount',
      1
    );
    await this.repository.update(
      { id, tenantId: ctx.tenantId },
      { lastUsedAt: new Date() }
    );
  }

  async getCategories(ctx: ServiceContext): Promise<string[]> {
    const quickReplies = await this.repository.find({
      where: { tenantId: ctx.tenantId },
      select: ['category'],
    });

    const categories = new Set<string>();
    quickReplies.forEach(qr => {
      if (qr.category) {
        categories.add(qr.category);
      }
    });

    return Array.from(categories).sort();
  }

  async getMostUsed(ctx: ServiceContext, limit: number = 10): Promise<QuickReply[]> {
    return this.repository.find({
      where: { tenantId: ctx.tenantId, isActive: true },
      order: { usageCount: 'DESC' },
      take: limit,
    });
  }

  async getStatistics(ctx: ServiceContext): Promise<{
    total: number;
    active: number;
    inactive: number;
    byCategory: Record<string, number>;
    byMessageType: Record<string, number>;
    totalUsage: number;
  }> {
    const quickReplies = await this.repository.find({
      where: { tenantId: ctx.tenantId },
    });

    const byCategory: Record<string, number> = {};
    const byMessageType: Record<string, number> = {};
    let totalUsage = 0;

    quickReplies.forEach(qr => {
      const cat = qr.category || 'uncategorized';
      byCategory[cat] = (byCategory[cat] || 0) + 1;
      byMessageType[qr.messageType] = (byMessageType[qr.messageType] || 0) + 1;
      totalUsage += qr.usageCount;
    });

    return {
      total: quickReplies.length,
      active: quickReplies.filter(qr => qr.isActive).length,
      inactive: quickReplies.filter(qr => !qr.isActive).length,
      byCategory,
      byMessageType,
      totalUsage,
    };
  }

  async duplicate(ctx: ServiceContext, id: string, newShortcut: string): Promise<QuickReply | null> {
    const quickReply = await this.findById(ctx, id);
    if (!quickReply) {
      return null;
    }

    const newQuickReply = this.repository.create({
      tenantId: ctx.tenantId,
      accountId: quickReply.accountId,
      shortcut: newShortcut,
      title: `${quickReply.title} (Copy)`,
      category: quickReply.category,
      messageType: quickReply.messageType,
      content: quickReply.content,
      mediaUrl: quickReply.mediaUrl,
      isActive: false,
      createdBy: ctx.userId,
    });

    return this.repository.save(newQuickReply);
  }
}
