/**
 * 메일 관리 시스템 API 클라이언트
 * 파일 기반 메일 계정 및 템플릿 관리
 */

// API 기본 URL
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "/api";

// ============================================
// 타입 정의
// ============================================

export interface MailAccount {
  id: string;
  name: string;
  email: string;
  smtpHost: string;
  smtpPort: number;
  smtpSecure: boolean;
  smtpUsername: string;
  smtpPassword: string; // 암호화된 상태
  dailyLimit: number;
  status: 'active' | 'inactive';
  createdAt: string;
  updatedAt: string;
}

export interface CreateMailAccountDto {
  name: string;
  email: string;
  smtpHost: string;
  smtpPort: number;
  smtpSecure: boolean;
  smtpUsername: string;
  smtpPassword: string;
  dailyLimit?: number;
}

export interface UpdateMailAccountDto extends Partial<CreateMailAccountDto> {
  status?: 'active' | 'inactive';
}

export interface MailComponent {
  id: string;
  type: 'text' | 'button' | 'image' | 'spacer' | 'header' | 'infoTable' | 'alertBox' | 'divider' | 'footer' | 'numberedList';
  content?: string;
  text?: string;
  url?: string;
  src?: string;
  height?: number;
  styles?: Record<string, string>;
  // 헤더 컴포넌트용
  logoSrc?: string;
  brandName?: string;
  sendDate?: string;
  headerBgColor?: string;
  // 정보 테이블용
  rows?: Array<{ label: string; value: string }>;
  tableTitle?: string;
  // 강조 박스용
  alertType?: 'info' | 'warning' | 'danger' | 'success';
  alertTitle?: string;
  // 푸터용
  companyName?: string;
  ceoName?: string;
  businessNumber?: string;
  address?: string;
  phone?: string;
  email?: string;
  copyright?: string;
  // 번호 리스트용
  listItems?: string[];
  listTitle?: string;
}

export interface MailTemplate {
  id: string;
  name: string;
  subject: string;
  components: MailComponent[];
  category?: string;
  createdAt: string;
  updatedAt: string;
}

export interface CreateMailTemplateDto {
  name: string;
  subject: string;
  components: MailComponent[];
  category?: string;
}

export interface UpdateMailTemplateDto extends Partial<CreateMailTemplateDto> {}

export interface SendMailDto {
  accountId: string;
  templateId?: string;
  to: string[]; // 받는 사람
  cc?: string[]; // 참조 (Carbon Copy)
  bcc?: string[]; // 숨은참조 (Blind Carbon Copy)
  subject: string;
  variables?: Record<string, string>; // 템플릿 변수 치환
  customHtml?: string; // 템플릿 없이 직접 HTML 작성 시
}

// ============================================
// 발송 이력 타입
// ============================================

export interface AttachmentInfo {
  filename: string;
  originalName: string;
  size: number;
  path: string;
  mimetype: string;
}

export interface SentMailHistory {
  id: string;
  accountId: string;
  accountName: string;
  accountEmail: string;
  to: string[];
  cc?: string[];
  bcc?: string[];
  subject: string;
  htmlContent: string;
  templateId?: string;
  templateName?: string;
  attachments?: AttachmentInfo[];
  sentAt: string;
  status: 'success' | 'failed' | 'draft';
  messageId?: string;
  errorMessage?: string;
  accepted?: string[];
  rejected?: string[];
  isDraft?: boolean;
  deletedAt?: string;
  updatedAt?: string;
}

export interface SentMailListQuery {
  page?: number;
  limit?: number;
  searchTerm?: string;
  status?: 'success' | 'failed' | 'draft' | 'all';
  accountId?: string;
  startDate?: string;
  endDate?: string;
  sortBy?: 'sentAt' | 'subject' | 'updatedAt';
  sortOrder?: 'asc' | 'desc';
  includeDeleted?: boolean;
  onlyDeleted?: boolean;
}

export interface SentMailListResponse {
  items: SentMailHistory[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface MailStatistics {
  totalSent: number;
  successCount: number;
  failedCount: number;
  todayCount: number;
  thisMonthCount: number;
  successRate: number;
}

export interface MailSendResult {
  success: boolean;
  messageId?: string;
  error?: string;
}

// ============================================
// API 기본 설정
// ============================================

import { apiClient } from './client';

async function fetchApi<T>(
  endpoint: string,
  options: { method?: string; data?: unknown } = {}
): Promise<T> {
  const { method = 'GET', data } = options;
  
  try {
    const response = await apiClient({
      url: endpoint, // `/mail` 접두사 제거 (apiClient는 이미 /api를 포함)
      method,
      data,
    });

    // 백엔드가 { success: true, data: ... } 형식으로 반환하는 경우 처리
    if (response.data.success && response.data.data !== undefined) {
      return response.data.data as T;
    }
    
    return response.data as T;
  } catch (error: unknown) {
    if (error && typeof error === 'object' && 'response' in error) {
      const axiosError = error as { response?: { data?: { message?: string }; status?: number } };
      throw new Error(axiosError.response?.data?.message || `HTTP ${axiosError.response?.status}`);
    }
    throw new Error('Unknown error');
  }
}

// ============================================
// 메일 계정 API
// ============================================

/**
 * 전체 메일 계정 목록 조회
 */
export async function getMailAccounts(): Promise<MailAccount[]> {
  return fetchApi<MailAccount[]>('/mail/accounts');
}

/**
 * 특정 메일 계정 조회
 */
export async function getMailAccount(id: string): Promise<MailAccount> {
  return fetchApi<MailAccount>(`/mail/accounts/${id}`);
}

/**
 * 메일 계정 생성
 */
export async function createMailAccount(
  data: CreateMailAccountDto
): Promise<MailAccount> {
  return fetchApi<MailAccount>('/mail/accounts', {
    method: 'POST',
    data,
  });
}

/**
 * 메일 계정 수정
 */
export async function updateMailAccount(
  id: string,
  data: UpdateMailAccountDto
): Promise<MailAccount> {
  return fetchApi<MailAccount>(`/mail/accounts/${id}`, {
    method: 'PUT',
    data,
  });
}

/**
 * 메일 계정 삭제
 */
export async function deleteMailAccount(id: string): Promise<{ success: boolean }> {
  return fetchApi<{ success: boolean }>(`/mail/accounts/${id}`, {
    method: 'DELETE',
  });
}

/**
 * SMTP 연결 테스트
 */
export async function testMailAccountConnection(id: string): Promise<{ success: boolean; message: string }> {
  return fetchApi<{ success: boolean; message: string }>(`/mail/accounts/${id}/test-connection`, {
    method: 'POST',
  });
}

/**
 * SMTP 연결 테스트
 */
export async function testMailConnection(id: string): Promise<{
  success: boolean;
  message: string;
}> {
  return fetchApi<{ success: boolean; message: string }>(
    `/mail/accounts/${id}/test-connection`,
    {
      method: 'POST',
    }
  );
}

// ============================================
// 메일 템플릿 API
// ============================================

/**
 * 전체 메일 템플릿 목록 조회
 */
export async function getMailTemplates(): Promise<MailTemplate[]> {
  return fetchApi<MailTemplate[]>('/mail/templates-file');
}

/**
 * 특정 메일 템플릿 조회
 */
export async function getMailTemplate(id: string): Promise<MailTemplate> {
  return fetchApi<MailTemplate>(`/mail/templates-file/${id}`);
}

/**
 * 메일 템플릿 생성
 */
export async function createMailTemplate(
  data: CreateMailTemplateDto
): Promise<MailTemplate> {
  return fetchApi<MailTemplate>('/mail/templates-file', {
    method: 'POST',
    data,
  });
}

/**
 * 메일 템플릿 수정
 */
export async function updateMailTemplate(
  id: string,
  data: UpdateMailTemplateDto
): Promise<MailTemplate> {
  return fetchApi<MailTemplate>(`/mail/templates-file/${id}`, {
    method: 'PUT',
    data,
  });
}

/**
 * 메일 템플릿 삭제
 */
export async function deleteMailTemplate(id: string): Promise<{ success: boolean }> {
  return fetchApi<{ success: boolean }>(`/mail/templates-file/${id}`, {
    method: 'DELETE',
  });
}

/**
 * 메일 템플릿 미리보기 (샘플 데이터)
 */
export async function previewMailTemplate(
  id: string,
  sampleData?: Record<string, string>
): Promise<{ html: string }> {
  return fetchApi<{ html: string }>(`/mail/templates-file/${id}/preview`, {
    method: 'POST',
    data: { sampleData },
  });
}

// ============================================
// 메일 발송 API (간단한 버전 - 쿼리 제외)
// ============================================

/**
 * 메일 발송 (단건 또는 소규모 발송)
 */
export async function sendMail(data: SendMailDto): Promise<MailSendResult> {
  return fetchApi<MailSendResult>('/mail/send/simple', {
    method: 'POST',
    data,
  });
}

/**
 * 대량 메일 발송
 */
export interface BulkSendRequest {
  accountId: string;
  templateId?: string; // 템플릿 ID (선택)
  customHtml?: string; // 직접 작성한 HTML (선택)
  subject: string;
  recipients: Array<{
    email: string;
    variables?: Record<string, string>; // 템플릿 사용 시에만 필요
  }>;
  onProgress?: (sent: number, total: number) => void;
}

export interface BulkSendResult {
  total: number;
  success: number;
  failed: number;
  results: Array<{
    email: string;
    success: boolean;
    messageId?: string;
    error?: string;
  }>;
}

export async function sendBulkMail(request: BulkSendRequest): Promise<BulkSendResult> {
  const { onProgress, ...data } = request;
  
  // 프로그레스 콜백이 있으면 시뮬레이션 (실제로는 서버에서 스트리밍 필요)
  if (onProgress) {
    onProgress(0, data.recipients.length);
  }
  
  const result = await fetchApi<BulkSendResult>('/mail/send/bulk', {
    method: 'POST',
    data,
  });
  
  if (onProgress) {
    onProgress(result.success, result.total);
  }
  
  return result;
}

/**
 * 템플릿 변수 추출 (템플릿에서 {변수명} 형식 추출)
 */
export function extractTemplateVariables(template: MailTemplate): string[] {
  const variableRegex = /\{(\w+)\}/g;
  const variables = new Set<string>();

  // subject에서 추출
  const subjectMatches = template.subject.matchAll(variableRegex);
  for (const match of subjectMatches) {
    variables.add(match[1]);
  }

  // 컴포넌트 content에서 추출
  template.components.forEach((component) => {
    if (component.content) {
      const contentMatches = component.content.matchAll(variableRegex);
      for (const match of contentMatches) {
        variables.add(match[1]);
      }
    }
    if (component.text) {
      const textMatches = component.text.matchAll(variableRegex);
      for (const match of textMatches) {
        variables.add(match[1]);
      }
    }
  });

  return Array.from(variables);
}

/**
 * 템플릿을 HTML로 렌더링 (프론트엔드 미리보기용)
 */
export function renderTemplateToHtml(
  template: MailTemplate,
  variables?: Record<string, string>
): string {
  let html = '<div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">';

  template.components.forEach((component) => {
    switch (component.type) {
      case 'text':
        let content = component.content || '';
        if (variables) {
          Object.entries(variables).forEach(([key, value]) => {
            content = content.replace(new RegExp(`\\{${key}\\}`, 'g'), value);
          });
        }
        html += `<div style="${styleObjectToString(component.styles)}">${content}</div>`;
        break;

      case 'button':
        let buttonText = component.text || 'Button';
        if (variables) {
          Object.entries(variables).forEach(([key, value]) => {
            buttonText = buttonText.replace(new RegExp(`\\{${key}\\}`, 'g'), value);
          });
        }
        html += `
          <a href="${component.url || '#'}" style="
            display: inline-block;
            padding: 12px 24px;
            background-color: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 4px;
            ${styleObjectToString(component.styles)}
          ">${buttonText}</a>
        `;
        break;

      case 'image':
        html += `<img src="${component.src || ''}" style="max-width: 100%; ${styleObjectToString(component.styles)}" />`;
        break;

      case 'spacer':
        html += `<div style="height: ${component.height || 20}px;"></div>`;
        break;

      case 'header':
        html += `
          <div style="padding: 20px; background-color: ${component.headerBgColor || '#f8f9fa'}; border-radius: 8px; margin-bottom: 20px;">
            <table style="width: 100%;">
              <tr>
                <td style="vertical-align: middle;">
                  ${component.logoSrc ? `<img src="${component.logoSrc}" alt="로고" style="height: 40px; margin-right: 12px;">` : ''}
                  <span style="font-size: 18px; font-weight: bold;">${component.brandName || ''}</span>
                </td>
                <td style="text-align: right; color: #6b7280; font-size: 14px;">
                  ${component.sendDate || ''}
                </td>
              </tr>
            </table>
          </div>
        `;
        break;

      case 'infoTable':
        html += `
          <div style="border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; margin: 16px 0;">
            ${component.tableTitle ? `<div style="background-color: #f9fafb; padding: 12px 16px; font-weight: 600; border-bottom: 1px solid #e5e7eb;">${component.tableTitle}</div>` : ''}
            <table style="width: 100%; border-collapse: collapse;">
              ${(component.rows || []).map((row, i) => `
                <tr style="background-color: ${i % 2 === 0 ? '#ffffff' : '#f9fafb'};">
                  <td style="padding: 12px 16px; font-weight: 500; color: #4b5563; width: 35%; border-right: 1px solid #e5e7eb;">${row.label}</td>
                  <td style="padding: 12px 16px;">${row.value}</td>
                </tr>
              `).join('')}
            </table>
          </div>
        `;
        break;

      case 'alertBox':
        const alertColors = {
          info: { bg: '#eff6ff', border: '#3b82f6', text: '#1e40af' },
          warning: { bg: '#fffbeb', border: '#f59e0b', text: '#92400e' },
          danger: { bg: '#fef2f2', border: '#ef4444', text: '#991b1b' },
          success: { bg: '#ecfdf5', border: '#10b981', text: '#065f46' }
        };
        const colors = alertColors[component.alertType || 'info'];
        html += `
          <div style="padding: 16px; background-color: ${colors.bg}; border-left: 4px solid ${colors.border}; border-radius: 4px; margin: 16px 0; color: ${colors.text};">
            ${component.alertTitle ? `<div style="font-weight: bold; margin-bottom: 8px;">${component.alertTitle}</div>` : ''}
            <div>${component.content || ''}</div>
          </div>
        `;
        break;

      case 'divider':
        html += `<hr style="border: none; border-top: ${component.height || 1}px solid #e5e7eb; margin: 20px 0;">`;
        break;

      case 'footer':
        html += `
          <div style="text-align: center; padding: 24px 16px; background-color: #f9fafb; border-top: 1px solid #e5e7eb; font-size: 14px; color: #6b7280;">
            ${component.companyName ? `<div style="font-weight: 600; color: #374151; margin-bottom: 8px;">${component.companyName}</div>` : ''}
            ${(component.ceoName || component.businessNumber) ? `
              <div style="margin-bottom: 4px;">
                ${component.ceoName ? `대표: ${component.ceoName}` : ''}
                ${component.ceoName && component.businessNumber ? ' | ' : ''}
                ${component.businessNumber ? `사업자등록번호: ${component.businessNumber}` : ''}
              </div>
            ` : ''}
            ${component.address ? `<div style="margin-bottom: 4px;">${component.address}</div>` : ''}
            ${(component.phone || component.email) ? `
              <div style="margin-bottom: 4px;">
                ${component.phone ? `Tel: ${component.phone}` : ''}
                ${component.phone && component.email ? ' | ' : ''}
                ${component.email ? `Email: ${component.email}` : ''}
              </div>
            ` : ''}
            ${component.copyright ? `<div style="margin-top: 12px; font-size: 12px; color: #9ca3af;">${component.copyright}</div>` : ''}
          </div>
        `;
        break;

      case 'numberedList':
        html += `
          <div style="padding: 16px; ${styleObjectToString(component.styles)}">
            ${component.listTitle ? `<div style="font-weight: 600; margin-bottom: 12px;">${component.listTitle}</div>` : ''}
            <ol style="margin: 0; padding-left: 20px;">
              ${(component.listItems || []).map(item => `<li style="margin-bottom: 8px;">${item}</li>`).join('')}
            </ol>
          </div>
        `;
        break;
    }
  });

  html += '</div>';
  return html;
}

function styleObjectToString(styles?: Record<string, string>): string {
  if (!styles) return '';
  return Object.entries(styles)
    .map(([key, value]) => `${camelToKebab(key)}: ${value}`)
    .join('; ');
}

function camelToKebab(str: string): string {
  return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
}

// ============================================
// 📥 메일 수신 API (Step 2)
// ============================================

export interface ReceivedMail {
  id: string;
  messageId: string;
  from: string;
  to: string;
  subject: string;
  date: string;
  preview: string;
  isRead: boolean;
  hasAttachments: boolean;
}

export interface MailDetail extends ReceivedMail {
  htmlBody: string;
  textBody: string;
  cc?: string;
  bcc?: string;
  attachments: Array<{
    filename: string;
    contentType: string;
    size: number;
  }>;
}

/**
 * 받은 메일 목록 조회
 */
export async function getReceivedMails(
  accountId: string,
  limit: number = 50
): Promise<ReceivedMail[]> {
  return fetchApi<ReceivedMail[]>(`/mail/receive/${accountId}?limit=${limit}`);
}

/**
 * 오늘 수신한 메일 수 조회 (통계)
 */
export async function getTodayReceivedCount(accountId?: string): Promise<number> {
  const params = accountId ? `?accountId=${accountId}` : '';
  const response = await fetchApi<{ count: number }>(`/mail/receive/today-count${params}`);
  return response.count;
}

/**
 * 메일 상세 조회
 */
export async function getMailDetail(
  accountId: string,
  seqno: number
): Promise<MailDetail> {
  return fetchApi<MailDetail>(`/mail/receive/${accountId}/${seqno}`);
}

/**
 * 메일 첨부파일 다운로드
 */
export async function downloadMailAttachment(
  accountId: string,
  seqno: number,
  attachmentIndex: number
): Promise<Blob> {
  const token = localStorage.getItem('authToken');
  const response = await fetch(
    `${API_BASE_URL}/mail/receive/${accountId}/${seqno}/attachment/${attachmentIndex}`,
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`첨부파일 다운로드 실패: ${response.status}`);
  }

  return response.blob();
}

/**
 * 메일을 읽음으로 표시
 */
export async function markMailAsRead(
  accountId: string,
  seqno: number
): Promise<{ success: boolean; message: string }> {
  return fetchApi(`/mail/receive/${accountId}/${seqno}/mark-read`, {
    method: 'POST',
  });
}

/**
 * IMAP 연결 테스트
 */
export async function testImapConnection(
  accountId: string
): Promise<{ success: boolean; message: string }> {
  return fetchApi(`/mail/receive/${accountId}/test-imap`, {
    method: 'POST',
  });
}

// ============================================
// 발송 이력 API
// ============================================

/**
 * 발송 이력 목록 조회
 */
export async function getSentMailList(
  query: SentMailListQuery = {}
): Promise<SentMailListResponse> {
  const params = new URLSearchParams();
  
  if (query.page) params.append('page', query.page.toString());
  if (query.limit) params.append('limit', query.limit.toString());
  if (query.searchTerm) params.append('searchTerm', query.searchTerm);
  if (query.status && query.status !== 'all') params.append('status', query.status);
  if (query.accountId) params.append('accountId', query.accountId);
  if (query.startDate) params.append('startDate', query.startDate);
  if (query.endDate) params.append('endDate', query.endDate);
  if (query.sortBy) params.append('sortBy', query.sortBy);
  if (query.sortOrder) params.append('sortOrder', query.sortOrder);
  if (query.includeDeleted) params.append('includeDeleted', 'true');
  if (query.onlyDeleted) params.append('onlyDeleted', 'true');

  return fetchApi(`/mail/sent?${params.toString()}`);
}

/**
 * 특정 발송 이력 상세 조회
 */
export async function getSentMailById(id: string): Promise<SentMailHistory> {
  return fetchApi(`/mail/sent/${id}`);
}

/**
 * 발송 이력 삭제 (Soft Delete)
 */
export async function deleteSentMail(id: string): Promise<{ success: boolean; message: string }> {
  return fetchApi(`/mail/sent/${id}`, {
    method: 'DELETE',
  });
}

/**
 * 임시 저장 (Draft)
 */
export async function saveDraft(data: Partial<SentMailHistory> & { accountId: string }): Promise<SentMailHistory> {
  const response = await apiClient.post('/mail/sent/draft', data);
  return response.data.data;
}

/**
 * 임시 저장 업데이트
 */
export async function updateDraft(id: string, data: Partial<SentMailHistory>): Promise<SentMailHistory> {
  const response = await apiClient.put(`/mail/sent/draft/${id}`, data);
  return response.data.data;
}

/**
 * 메일 복구
 */
export async function restoreMail(id: string): Promise<{ success: boolean; message: string }> {
  return fetchApi(`/mail/sent/${id}/restore`, {
    method: 'POST',
  });
}

/**
 * 메일 영구 삭제
 */
export async function permanentlyDeleteMail(id: string): Promise<{ success: boolean; message: string }> {
  return fetchApi(`/mail/sent/${id}/permanent`, {
    method: 'DELETE',
  });
}

/**
 * 일괄 삭제
 */
export async function bulkDeleteMails(ids: string[]): Promise<{ success: boolean; message: string; data: { successCount: number; failCount: number } }> {
  return fetchApi('/mail/sent/bulk/delete', {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

/**
 * 일괄 영구 삭제
 */
export async function bulkPermanentlyDeleteMails(ids: string[]): Promise<{ success: boolean; message: string; data: { successCount: number; failCount: number } }> {
  return fetchApi('/mail/sent/bulk/permanent-delete', {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

/**
 * 일괄 복구
 */
export async function bulkRestoreMails(ids: string[]): Promise<{ success: boolean; message: string; data: { successCount: number; failCount: number } }> {
  return fetchApi('/mail/sent/bulk/restore', {
    method: 'POST',
    body: JSON.stringify({ ids }),
  });
}

/**
 * 메일 발송 통계 조회
 */
export async function getMailStatistics(accountId?: string): Promise<MailStatistics> {
  const params = accountId ? `?accountId=${accountId}` : '';
  return fetchApi(`/mail/sent/statistics${params}`);
}
