import { IsString, IsNumber, IsOptional, IsArray, IsEnum, IsBoolean, IsEmail } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

/**
 * FreeScout API Types and DTOs
 */

// ============ Enums ============

export enum ConversationStatus {
  ACTIVE = 'active',
  PENDING = 'pending',
  CLOSED = 'closed',
  SPAM = 'spam',
}

export enum ConversationType {
  EMAIL = 'email',
  PHONE = 'phone',
  CHAT = 'chat',
}

export enum ThreadType {
  CUSTOMER = 'customer',
  MESSAGE = 'message',
  NOTE = 'note',
  LINEITEM = 'lineitem',
}

export enum ThreadStatus {
  ACTIVE = 'active',
  CLOSED = 'closed',
  NOCHANGE = 'nochange',
  PENDING = 'pending',
  SPAM = 'spam',
}

// ============ API Response Types ============

export interface FreeScoutMailbox {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface FreeScoutCustomer {
  id: number;
  firstName: string;
  lastName: string;
  email: string;
  emails: string[];
  phones: string[];
  company: string | null;
  jobTitle: string | null;
  photoUrl: string | null;
  notes: string | null;
  createdAt: string;
  updatedAt: string;
}

export interface FreeScoutUser {
  id: number;
  firstName: string;
  lastName: string;
  email: string;
  role: string;
  photoUrl: string | null;
}

export interface FreeScoutThread {
  id: number;
  type: ThreadType;
  status: ThreadStatus;
  state: string;
  body: string;
  source: {
    type: string;
    via: string;
  };
  customer: FreeScoutCustomer | null;
  user: FreeScoutUser | null;
  createdAt: string;
  attachments: FreeScoutAttachment[];
}

export interface FreeScoutAttachment {
  id: number;
  fileName: string;
  mimeType: string;
  size: number;
  url: string;
}

export interface FreeScoutConversation {
  id: number;
  number: number;
  type: ConversationType;
  folderId: number;
  status: ConversationStatus;
  state: string;
  subject: string;
  preview: string;
  mailboxId: number;
  assignee: FreeScoutUser | null;
  createdBy: FreeScoutUser | null;
  createdAt: string;
  updatedAt: string;
  closedAt: string | null;
  closedBy: FreeScoutUser | null;
  userUpdatedAt: string | null;
  customerWaitingSince: {
    time: string;
    friendly: string;
  } | null;
  customer: FreeScoutCustomer;
  threads: FreeScoutThread[];
  tags: FreeScoutTag[];
  customFields: Record<string, unknown>;
}

export interface FreeScoutTag {
  id: number;
  name: string;
  color: string | null;
}

export interface FreeScoutPagination {
  current_page: number;
  from: number;
  last_page: number;
  per_page: number;
  to: number;
  total: number;
}

export interface FreeScoutListResponse<T> {
  _embedded: {
    conversations?: T[];
    customers?: T[];
    mailboxes?: T[];
    tags?: T[];
  };
  page: FreeScoutPagination;
}

// ============ DTOs ============

export class ListConversationsDto {
  @ApiPropertyOptional({ description: 'Mailbox ID to filter conversations' })
  @IsOptional()
  @IsNumber()
  mailboxId?: number;

  @ApiPropertyOptional({ description: 'Status filter', enum: ConversationStatus })
  @IsOptional()
  @IsEnum(ConversationStatus)
  status?: ConversationStatus;

  @ApiPropertyOptional({ description: 'Assigned user ID' })
  @IsOptional()
  @IsNumber()
  assignedTo?: number;

  @ApiPropertyOptional({ description: 'Tag to filter by' })
  @IsOptional()
  @IsString()
  tag?: string;

  @ApiPropertyOptional({ description: 'Page number', default: 1 })
  @IsOptional()
  @IsNumber()
  page?: number;

  @ApiPropertyOptional({ description: 'Items per page', default: 50 })
  @IsOptional()
  @IsNumber()
  pageSize?: number;
}

export class CreateConversationDto {
  @ApiProperty({ description: 'Conversation type', enum: ConversationType })
  @IsEnum(ConversationType)
  type: ConversationType;

  @ApiProperty({ description: 'Subject line' })
  @IsString()
  subject: string;

  @ApiProperty({ description: 'Mailbox ID' })
  @IsNumber()
  mailboxId: number;

  @ApiProperty({ description: 'Customer email address' })
  @IsEmail()
  customerEmail: string;

  @ApiPropertyOptional({ description: 'Customer first name' })
  @IsOptional()
  @IsString()
  customerFirstName?: string;

  @ApiPropertyOptional({ description: 'Customer last name' })
  @IsOptional()
  @IsString()
  customerLastName?: string;

  @ApiProperty({ description: 'Initial message body (HTML allowed)' })
  @IsString()
  body: string;

  @ApiPropertyOptional({ description: 'Tags to assign', type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  tags?: string[];

  @ApiPropertyOptional({ description: 'User ID to assign the conversation to' })
  @IsOptional()
  @IsNumber()
  assignTo?: number;

  @ApiPropertyOptional({ description: 'Initial status', enum: ConversationStatus })
  @IsOptional()
  @IsEnum(ConversationStatus)
  status?: ConversationStatus;
}

export class ReplyToConversationDto {
  @ApiProperty({ description: 'Reply body (HTML allowed)' })
  @IsString()
  body: string;

  @ApiPropertyOptional({ description: 'Thread type', enum: ThreadType, default: ThreadType.MESSAGE })
  @IsOptional()
  @IsEnum(ThreadType)
  type?: ThreadType;

  @ApiPropertyOptional({ description: 'User ID sending the reply' })
  @IsOptional()
  @IsNumber()
  userId?: number;

  @ApiPropertyOptional({ description: 'Status after reply', enum: ConversationStatus })
  @IsOptional()
  @IsEnum(ConversationStatus)
  status?: ConversationStatus;

  @ApiPropertyOptional({ description: 'Mark as draft (not sent)', default: false })
  @IsOptional()
  @IsBoolean()
  draft?: boolean;

  @ApiPropertyOptional({ description: 'CC recipients', type: [String] })
  @IsOptional()
  @IsArray()
  @IsEmail({}, { each: true })
  cc?: string[];

  @ApiPropertyOptional({ description: 'BCC recipients', type: [String] })
  @IsOptional()
  @IsArray()
  @IsEmail({}, { each: true })
  bcc?: string[];
}

export class CreateCustomerDto {
  @ApiProperty({ description: 'Customer email address' })
  @IsEmail()
  email: string;

  @ApiPropertyOptional({ description: 'First name' })
  @IsOptional()
  @IsString()
  firstName?: string;

  @ApiPropertyOptional({ description: 'Last name' })
  @IsOptional()
  @IsString()
  lastName?: string;

  @ApiPropertyOptional({ description: 'Company name' })
  @IsOptional()
  @IsString()
  company?: string;

  @ApiPropertyOptional({ description: 'Job title' })
  @IsOptional()
  @IsString()
  jobTitle?: string;

  @ApiPropertyOptional({ description: 'Phone numbers', type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  phones?: string[];

  @ApiPropertyOptional({ description: 'Notes about the customer' })
  @IsOptional()
  @IsString()
  notes?: string;
}

export class ListCustomersDto {
  @ApiPropertyOptional({ description: 'Search by email' })
  @IsOptional()
  @IsEmail()
  email?: string;

  @ApiPropertyOptional({ description: 'Search query' })
  @IsOptional()
  @IsString()
  query?: string;

  @ApiPropertyOptional({ description: 'Page number', default: 1 })
  @IsOptional()
  @IsNumber()
  page?: number;

  @ApiPropertyOptional({ description: 'Items per page', default: 50 })
  @IsOptional()
  @IsNumber()
  pageSize?: number;
}

// ============ Response DTOs ============

export class ConversationResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  number: number;

  @ApiProperty({ enum: ConversationType })
  type: ConversationType;

  @ApiProperty({ enum: ConversationStatus })
  status: ConversationStatus;

  @ApiProperty()
  subject: string;

  @ApiProperty()
  preview: string;

  @ApiProperty()
  mailboxId: number;

  @ApiPropertyOptional()
  assignee?: FreeScoutUser;

  @ApiProperty()
  customer: FreeScoutCustomer;

  @ApiProperty()
  createdAt: string;

  @ApiProperty()
  updatedAt: string;

  @ApiPropertyOptional({ type: [Object] })
  threads?: FreeScoutThread[];

  @ApiPropertyOptional({ type: [Object] })
  tags?: FreeScoutTag[];
}

export class MailboxResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  email: string;

  @ApiProperty()
  isActive: boolean;
}

export class CustomerResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  firstName: string;

  @ApiProperty()
  lastName: string;

  @ApiProperty()
  email: string;

  @ApiPropertyOptional({ type: [String] })
  emails?: string[];

  @ApiPropertyOptional()
  company?: string;

  @ApiPropertyOptional()
  jobTitle?: string;

  @ApiProperty()
  createdAt: string;
}

export class TagResponseDto {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiPropertyOptional()
  color?: string;
}
