import fp from 'fastify-plugin';
import { MeiliSearch } from 'meilisearch';

const INDEX_NAME = 'schedules';

async function meilisearchPlugin(fastify, opts) {
  const { host, apiKey } = fastify.config.meilisearch;

  const client = new MeiliSearch({
    host,
    apiKey,
  });

  // 연결 테스트 및 인덱스 초기화
  try {
    await client.health();
    fastify.log.info('Meilisearch 연결 성공');

    // 인덱스 초기화
    await initIndex(client, fastify.log);
  } catch (err) {
    fastify.log.error('Meilisearch 연결 실패:', err.message);
    // Meilisearch가 없어도 서버는 동작하도록 에러를 던지지 않음
  }

  fastify.decorate('meilisearch', client);
  fastify.decorate('meilisearchIndex', INDEX_NAME);
}

/**
 * 인덱스 초기화 및 설정
 */
async function initIndex(client, log) {
  try {
    // 인덱스 생성 (이미 존재하면 무시)
    try {
      await client.createIndex(INDEX_NAME, { primaryKey: 'id' });
    } catch (err) {
      // 이미 존재하는 경우 무시
    }

    const index = client.index(INDEX_NAME);

    // 검색 가능한 필드 설정 (순서가 우선순위 결정)
    await index.updateSearchableAttributes([
      'title',
      'member_names',
      'description',
      'source_name',
      'category_name',
    ]);

    // 필터링 가능한 필드 설정
    await index.updateFilterableAttributes(['category_id', 'date']);

    // 정렬 가능한 필드 설정
    await index.updateSortableAttributes(['date', 'time']);

    // 랭킹 규칙 설정 (동일 유사도일 때 최신 날짜 우선)
    await index.updateRankingRules([
      'words',
      'typo',
      'proximity',
      'attribute',
      'exactness',
      'date:desc',
    ]);

    // 오타 허용 설정
    await index.updateTypoTolerance({
      enabled: true,
      minWordSizeForTypos: {
        oneTypo: 2,
        twoTypos: 4,
      },
    });

    // 페이징 설정
    await index.updatePagination({
      maxTotalHits: 10000,
    });

    log.info('Meilisearch 인덱스 초기화 완료');
  } catch (err) {
    log.error('Meilisearch 인덱스 초기화 오류:', err.message);
  }
}

export default fp(meilisearchPlugin, {
  name: 'meilisearch',
  dependencies: ['db'],
});
