/**
 * M-Project API 연동 서비스
 *
 * TK-FB-Project의 부적합 신고를 M-Project로 전송하는 서비스
 *
 * @author TK-FB-Project
 * @since 2026-02-03
 */

const logger = require('../utils/logger');

// M-Project API 설정
const M_PROJECT_CONFIG = {
  baseUrl: process.env.M_PROJECT_API_URL || 'http://localhost:16080',
  username: process.env.M_PROJECT_USERNAME || 'api_service',
  password: process.env.M_PROJECT_PASSWORD || '',
  defaultProjectId: parseInt(process.env.M_PROJECT_DEFAULT_PROJECT_ID) || 1,
};

// 캐시된 인증 토큰
let cachedToken = null;
let tokenExpiry = null;

/**
 * TK-FB 카테고리를 M-Project 카테고리로 매핑
 * @param {string} tkCategory - TK-FB-Project 카테고리
 * @returns {string} M-Project 카테고리
 */
function mapCategoryToMProject(tkCategory) {
  const categoryMap = {
    // TK-FB 카테고리 → M-Project 카테고리
    '자재 누락': 'material_missing',
    '자재누락': 'material_missing',
    '자재 관련': 'material_missing',
    '설계 오류': 'design_error',
    '설계미스': 'design_error',
    '설계 관련': 'design_error',
    '입고 불량': 'incoming_defect',
    '입고자재 불량': 'incoming_defect',
    '입고 관련': 'incoming_defect',
    '검사 미스': 'inspection_miss',
    '검사미스': 'inspection_miss',
    '검사 관련': 'inspection_miss',
    '기타': 'etc',
  };

  // 정확히 매칭되는 경우
  if (categoryMap[tkCategory]) {
    return categoryMap[tkCategory];
  }

  // 부분 매칭 시도
  const lowerCategory = tkCategory?.toLowerCase() || '';
  if (lowerCategory.includes('자재') || lowerCategory.includes('material')) {
    return 'material_missing';
  }
  if (lowerCategory.includes('설계') || lowerCategory.includes('design')) {
    return 'design_error';
  }
  if (lowerCategory.includes('입고') || lowerCategory.includes('incoming')) {
    return 'incoming_defect';
  }
  if (lowerCategory.includes('검사') || lowerCategory.includes('inspection')) {
    return 'inspection_miss';
  }

  // 기본값
  return 'etc';
}

/**
 * M-Project API 인증 토큰 획득
 * @returns {Promise<string|null>} JWT 토큰
 */
async function getAuthToken() {
  // 캐시된 토큰이 유효하면 재사용
  if (cachedToken && tokenExpiry && new Date() < tokenExpiry) {
    return cachedToken;
  }

  try {
    const formData = new URLSearchParams();
    formData.append('username', M_PROJECT_CONFIG.username);
    formData.append('password', M_PROJECT_CONFIG.password);

    const response = await fetch(`${M_PROJECT_CONFIG.baseUrl}/api/auth/login`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: formData.toString(),
    });

    if (!response.ok) {
      const errorText = await response.text();
      logger.error('M-Project 인증 실패', {
        status: response.status,
        error: errorText
      });
      return null;
    }

    const data = await response.json();
    cachedToken = data.access_token;

    // 토큰 만료 시간 설정 (기본 6일, M-Project는 7일 유효)
    tokenExpiry = new Date(Date.now() + 6 * 24 * 60 * 60 * 1000);

    logger.info('M-Project 인증 성공');
    return cachedToken;
  } catch (error) {
    logger.error('M-Project 인증 요청 오류', { error: error.message });
    return null;
  }
}

/**
 * 이미지 URL을 Base64로 변환
 * @param {string} imageUrl - 이미지 URL 또는 경로
 * @returns {Promise<string|null>} Base64 인코딩된 이미지
 */
async function convertImageToBase64(imageUrl) {
  if (!imageUrl) return null;

  try {
    // 이미 Base64인 경우 그대로 반환
    if (imageUrl.startsWith('data:image')) {
      return imageUrl;
    }

    // URL인 경우 fetch
    if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {
      const response = await fetch(imageUrl);
      if (!response.ok) return null;

      const buffer = await response.arrayBuffer();
      const base64 = Buffer.from(buffer).toString('base64');
      const contentType = response.headers.get('content-type') || 'image/jpeg';
      return `data:${contentType};base64,${base64}`;
    }

    // 로컬 파일 경로인 경우
    const fs = require('fs').promises;
    const path = require('path');
    const filePath = path.join(process.cwd(), 'uploads', imageUrl);

    try {
      const fileBuffer = await fs.readFile(filePath);
      const base64 = fileBuffer.toString('base64');
      const ext = path.extname(imageUrl).toLowerCase();
      const mimeTypes = {
        '.jpg': 'image/jpeg',
        '.jpeg': 'image/jpeg',
        '.png': 'image/png',
        '.gif': 'image/gif',
        '.webp': 'image/webp',
      };
      const contentType = mimeTypes[ext] || 'image/jpeg';
      return `data:${contentType};base64,${base64}`;
    } catch {
      return null;
    }
  } catch (error) {
    logger.warn('이미지 Base64 변환 실패', { imageUrl, error: error.message });
    return null;
  }
}

/**
 * TK-FB-Project 부적합 신고를 M-Project로 전송
 *
 * @param {Object} issueData - 부적합 신고 데이터
 * @param {string} issueData.category - 카테고리 이름
 * @param {string} issueData.description - 신고 내용
 * @param {string} issueData.reporter_name - 신고자 이름
 * @param {string} issueData.project_name - 프로젝트 이름 (옵션)
 * @param {number} issueData.tk_issue_id - TK-FB-Project 이슈 ID
 * @param {string[]} issueData.photos - 사진 URL 배열 (최대 5개)
 * @returns {Promise<{success: boolean, mProjectId?: number, error?: string}>}
 */
async function sendToMProject(issueData) {
  const {
    category,
    description,
    reporter_name,
    project_name,
    tk_issue_id,
    photos = [],
  } = issueData;

  logger.info('M-Project 연동 시작', { tk_issue_id, category });

  // 인증 토큰 획득
  const token = await getAuthToken();
  if (!token) {
    return { success: false, error: 'M-Project 인증 실패' };
  }

  try {
    // 카테고리 매핑
    const mProjectCategory = mapCategoryToMProject(category);

    // 설명에 TK-FB 정보 추가
    const enhancedDescription = [
      description,
      '',
      '---',
      `[TK-FB-Project 연동]`,
      `- 원본 이슈 ID: ${tk_issue_id}`,
      `- 신고자: ${reporter_name || '미상'}`,
      project_name ? `- 프로젝트: ${project_name}` : null,
    ].filter(Boolean).join('\n');

    // 사진 변환 (최대 5개)
    const photoPromises = photos.slice(0, 5).map(convertImageToBase64);
    const base64Photos = await Promise.all(photoPromises);

    // 요청 본문 구성
    const requestBody = {
      category: mProjectCategory,
      description: enhancedDescription,
      project_id: M_PROJECT_CONFIG.defaultProjectId,
    };

    // 사진 추가
    base64Photos.forEach((photo, index) => {
      if (photo) {
        const fieldName = index === 0 ? 'photo' : `photo${index + 1}`;
        requestBody[fieldName] = photo;
      }
    });

    // M-Project API 호출
    const response = await fetch(`${M_PROJECT_CONFIG.baseUrl}/api/issues`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: JSON.stringify(requestBody),
    });

    if (!response.ok) {
      const errorText = await response.text();
      logger.error('M-Project 이슈 생성 실패', {
        status: response.status,
        error: errorText,
        tk_issue_id
      });
      return {
        success: false,
        error: `M-Project API 오류: ${response.status}`
      };
    }

    const createdIssue = await response.json();

    logger.info('M-Project 이슈 생성 성공', {
      tk_issue_id,
      m_project_id: createdIssue.id
    });

    return {
      success: true,
      mProjectId: createdIssue.id
    };
  } catch (error) {
    logger.error('M-Project 연동 오류', {
      tk_issue_id,
      error: error.message
    });
    return {
      success: false,
      error: error.message
    };
  }
}

/**
 * M-Project에서 이슈 상태 조회
 *
 * @param {number} mProjectId - M-Project 이슈 ID
 * @returns {Promise<{success: boolean, status?: string, data?: Object, error?: string}>}
 */
async function getIssueStatus(mProjectId) {
  const token = await getAuthToken();
  if (!token) {
    return { success: false, error: 'M-Project 인증 실패' };
  }

  try {
    const response = await fetch(
      `${M_PROJECT_CONFIG.baseUrl}/api/issues/${mProjectId}`,
      {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${token}`,
        },
      }
    );

    if (!response.ok) {
      return {
        success: false,
        error: `M-Project API 오류: ${response.status}`
      };
    }

    const data = await response.json();

    return {
      success: true,
      status: data.review_status || data.status,
      data
    };
  } catch (error) {
    return {
      success: false,
      error: error.message
    };
  }
}

/**
 * M-Project 상태를 TK-FB 상태로 매핑
 * @param {string} mProjectStatus - M-Project 상태
 * @returns {string} TK-FB-Project 상태
 */
function mapStatusFromMProject(mProjectStatus) {
  const statusMap = {
    'pending_review': 'received',
    'in_progress': 'in_progress',
    'completed': 'completed',
    'disposed': 'closed',
  };
  return statusMap[mProjectStatus] || 'received';
}

/**
 * M-Project 연결 테스트
 * @returns {Promise<{success: boolean, message: string}>}
 */
async function testConnection() {
  try {
    const token = await getAuthToken();
    if (!token) {
      return { success: false, message: 'M-Project 인증 실패' };
    }

    // /api/auth/me로 연결 테스트
    const response = await fetch(`${M_PROJECT_CONFIG.baseUrl}/api/auth/me`, {
      headers: {
        'Authorization': `Bearer ${token}`,
      },
    });

    if (response.ok) {
      const user = await response.json();
      return {
        success: true,
        message: `M-Project 연결 성공 (사용자: ${user.username})`
      };
    } else {
      return {
        success: false,
        message: `M-Project 연결 실패: ${response.status}`
      };
    }
  } catch (error) {
    return {
      success: false,
      message: `M-Project 연결 오류: ${error.message}`
    };
  }
}

module.exports = {
  sendToMProject,
  getIssueStatus,
  mapStatusFromMProject,
  testConnection,
  mapCategoryToMProject,
};
