import { Injectable, Logger } from '@nestjs/common';
import { FreeScoutConnector, ConnectorHealth } from './freescout.connector';
import {
  ListConversationsDto,
  CreateConversationDto,
  ReplyToConversationDto,
  CreateCustomerDto,
  ListCustomersDto,
  FreeScoutConversation,
  FreeScoutCustomer,
  FreeScoutMailbox,
  FreeScoutTag,
} from './freescout.types';

/**
 * FreeScout Service
 *
 * High-level service for interacting with FreeScout helpdesk.
 * Wraps the connector with additional business logic and logging.
 */
@Injectable()
export class FreeScoutService {
  private readonly logger = new Logger(FreeScoutService.name);

  constructor(private readonly connector: FreeScoutConnector) {}

  // ============ Health & Status ============

  /**
   * Check health status of the FreeScout integration
   */
  async checkHealth(): Promise<ConnectorHealth> {
    this.logger.debug('Checking FreeScout connector health');
    return this.connector.checkHealth();
  }

  /**
   * Test connection to FreeScout
   */
  async testConnection(): Promise<{ success: boolean; message: string; latency?: number }> {
    this.logger.log('Testing FreeScout connection');
    const result = await this.connector.testConnection();
    this.logger.log(`FreeScout connection test: ${result.success ? 'SUCCESS' : 'FAILED'} - ${result.message}`);
    return result;
  }

  /**
   * Check if connector is configured
   */
  isConfigured(): boolean {
    return this.connector.getIsConfigured();
  }

  // ============ Conversations ============

  /**
   * List conversations with optional filters
   */
  async listConversations(params: ListConversationsDto = {}): Promise<{
    conversations: FreeScoutConversation[];
    pagination: { page: number; pageSize: number; total: number; totalPages: number };
  }> {
    this.logger.debug(`Listing conversations with params: ${JSON.stringify(params)}`);
    const result = await this.connector.listConversations(params);
    this.logger.debug(`Found ${result.conversations.length} conversations`);
    return result;
  }

  /**
   * Get a single conversation by ID
   */
  async getConversation(id: number): Promise<FreeScoutConversation> {
    this.logger.debug(`Getting conversation: ${id}`);
    return this.connector.getConversation(id);
  }

  /**
   * Create a new conversation (ticket)
   */
  async createConversation(data: CreateConversationDto): Promise<FreeScoutConversation> {
    this.logger.log(`Creating new conversation: ${data.subject} for ${data.customerEmail}`);
    const conversation = await this.connector.createConversation(data);
    this.logger.log(`Created conversation #${conversation.number} (ID: ${conversation.id})`);
    return conversation;
  }

  /**
   * Reply to an existing conversation
   */
  async replyToConversation(
    conversationId: number,
    data: ReplyToConversationDto,
  ): Promise<FreeScoutConversation> {
    this.logger.log(`Replying to conversation: ${conversationId}`);
    const conversation = await this.connector.replyToConversation(conversationId, data);
    this.logger.log(`Added reply to conversation #${conversation.number}`);
    return conversation;
  }

  /**
   * Close a conversation
   */
  async closeConversation(conversationId: number): Promise<FreeScoutConversation> {
    this.logger.log(`Closing conversation: ${conversationId}`);
    const conversation = await this.connector.updateConversationStatus(conversationId, 'closed');
    this.logger.log(`Closed conversation #${conversation.number}`);
    return conversation;
  }

  /**
   * Reopen a conversation
   */
  async reopenConversation(conversationId: number): Promise<FreeScoutConversation> {
    this.logger.log(`Reopening conversation: ${conversationId}`);
    const conversation = await this.connector.updateConversationStatus(conversationId, 'active');
    this.logger.log(`Reopened conversation #${conversation.number}`);
    return conversation;
  }

  // ============ Mailboxes ============

  /**
   * List all mailboxes
   */
  async listMailboxes(): Promise<FreeScoutMailbox[]> {
    this.logger.debug('Listing mailboxes');
    const mailboxes = await this.connector.listMailboxes();
    this.logger.debug(`Found ${mailboxes.length} mailboxes`);
    return mailboxes;
  }

  /**
   * Get a single mailbox by ID
   */
  async getMailbox(id: number): Promise<FreeScoutMailbox> {
    this.logger.debug(`Getting mailbox: ${id}`);
    return this.connector.getMailbox(id);
  }

  // ============ Customers ============

  /**
   * List customers with optional filters
   */
  async listCustomers(params: ListCustomersDto = {}): Promise<{
    customers: FreeScoutCustomer[];
    pagination: { page: number; pageSize: number; total: number; totalPages: number };
  }> {
    this.logger.debug(`Listing customers with params: ${JSON.stringify(params)}`);
    const result = await this.connector.listCustomers(params);
    this.logger.debug(`Found ${result.customers.length} customers`);
    return result;
  }

  /**
   * Get a single customer by ID
   */
  async getCustomer(id: number): Promise<FreeScoutCustomer> {
    this.logger.debug(`Getting customer: ${id}`);
    return this.connector.getCustomer(id);
  }

  /**
   * Create a new customer
   */
  async createCustomer(data: CreateCustomerDto): Promise<FreeScoutCustomer> {
    this.logger.log(`Creating customer: ${data.email}`);
    const customer = await this.connector.createCustomer(data);
    this.logger.log(`Created customer: ${customer.id}`);
    return customer;
  }

  /**
   * Find or create a customer by email
   */
  async findOrCreateCustomer(data: CreateCustomerDto): Promise<FreeScoutCustomer> {
    this.logger.debug(`Finding or creating customer: ${data.email}`);

    // Try to find existing customer
    const existing = await this.connector.findCustomerByEmail(data.email);
    if (existing) {
      this.logger.debug(`Found existing customer: ${existing.id}`);
      return existing;
    }

    // Create new customer
    this.logger.log(`Customer not found, creating: ${data.email}`);
    return this.createCustomer(data);
  }

  // ============ Tags ============

  /**
   * List all tags
   */
  async listTags(): Promise<FreeScoutTag[]> {
    this.logger.debug('Listing tags');
    const tags = await this.connector.listTags();
    this.logger.debug(`Found ${tags.length} tags`);
    return tags;
  }

  /**
   * Add tags to a conversation
   */
  async addTagsToConversation(conversationId: number, tags: string[]): Promise<void> {
    this.logger.log(`Adding tags to conversation ${conversationId}: ${tags.join(', ')}`);
    await this.connector.addTagsToConversation(conversationId, tags);
    this.logger.log(`Added ${tags.length} tags to conversation ${conversationId}`);
  }
}
