import { describe, it, expect } from 'vitest';
import { ADMIN_EMAILS, formatAuthorName } from '@/lib/constants';

describe('ADMIN_EMAILS', () => {
    it('관리자 이메일 배열을 포함한다', () => {
        expect(ADMIN_EMAILS).toContain('jonghyuk.jeon@gmail.com');
        expect(ADMIN_EMAILS).toContain('drumbrab@gmail.com');
    });
});

describe('formatAuthorName', () => {
    it('jonghyuk.jeon을 전종혁으로 변환한다', () => {
        expect(formatAuthorName('jonghyuk.jeon')).toBe('전종혁');
    });

    it('일반 이름은 그대로 반환한다', () => {
        expect(formatAuthorName('홍길동')).toBe('홍길동');
    });

    it('null은 이름 없음을 반환한다', () => {
        expect(formatAuthorName(null)).toBe('이름 없음');
    });

    it('undefined는 이름 없음을 반환한다', () => {
        expect(formatAuthorName(undefined)).toBe('이름 없음');
    });
});

// ── 출처/신뢰도 관련 함수 테스트 (Phase 2) ──────────────────
import { getDefaultAuthorityTier, getAuthorityBadgeInfo, SOURCE_CHIP_MAP, SOURCE_CHIP_KEYS, SOURCE_TYPE_LABEL, VERIFICATION_LABEL } from '@/lib/constants';

describe('getDefaultAuthorityTier', () => {
  it('policy_pdf는 tier 1을 반환한다', () => {
    expect(getDefaultAuthorityTier('policy_pdf')).toBe(1);
  });

  it('kakao_expert는 tier 3.5를 반환한다', () => {
    expect(getDefaultAuthorityTier('kakao_expert')).toBe(3.5);
  });

  it('youtube는 tier 4를 반환한다', () => {
    expect(getDefaultAuthorityTier('youtube')).toBe(4);
  });

  it('모든 sourceType에 대해 유효한 tier를 반환한다', () => {
    const allTypes = ['policy_pdf', 'regulation', 'newsletter', 'court_ruling', 'wiki_editorial', 'kakao_expert', 'kakao_community', 'youtube', 'user_submitted'] as const;
    for (const st of allTypes) {
      const tier = getDefaultAuthorityTier(st);
      expect(tier).toBeGreaterThanOrEqual(1);
      expect(tier).toBeLessThanOrEqual(5);
    }
  });
});

describe('getAuthorityBadgeInfo', () => {
  it('tier 1은 공식(약관) 배지를 반환한다', () => {
    const badge = getAuthorityBadgeInfo(1);
    expect(badge.label).toBe('약관');
    expect(badge.colorClass).toContain('blue');
    expect(badge.icon).toBe('🛡️');
  });

  it('tier 1.5는 금감원 배지를 반환한다', () => {
    const badge = getAuthorityBadgeInfo(1.5);
    expect(badge.label).toBe('금감원');
  });

  it('tier 3은 전문가 배지를 반환한다', () => {
    const badge = getAuthorityBadgeInfo(3);
    expect(badge.label).toBe('전문가');
    expect(badge.colorClass).toContain('emerald');
  });

  it('tier 4는 참고용 배지를 반환한다', () => {
    const badge = getAuthorityBadgeInfo(4);
    expect(badge.label).toBe('참고용');
    expect(badge.colorClass).toContain('gray');
  });

  it('tier 없이 sourceType만으로 배지를 추론한다', () => {
    const badge = getAuthorityBadgeInfo(undefined, 'policy_pdf');
    expect(badge.label).toBe('약관');
  });

  it('tier와 sourceType 모두 없으면 일반 배지를 반환한다', () => {
    const badge = getAuthorityBadgeInfo();
    expect(badge.label).toBe('일반');
  });
});

describe('SOURCE_CHIP_MAP', () => {
  it('전체 칩은 null을 매핑한다', () => {
    expect(SOURCE_CHIP_MAP['전체']).toBeNull();
  });

  it('약관 칩은 policy_pdf를 포함한다', () => {
    expect(SOURCE_CHIP_MAP['약관']).toContain('policy_pdf');
  });

  it('전문가 칩은 kakao_expert, newsletter, wiki_editorial을 포함한다', () => {
    const types = SOURCE_CHIP_MAP['전문가'];
    expect(types).toContain('kakao_expert');
    expect(types).toContain('newsletter');
    expect(types).toContain('wiki_editorial');
  });

  it('커뮤니티 칩은 youtube, kakao_community, user_submitted를 포함한다', () => {
    const types = SOURCE_CHIP_MAP['커뮤니티'];
    expect(types).toContain('youtube');
    expect(types).toContain('kakao_community');
    expect(types).toContain('user_submitted');
  });
});

describe('SOURCE_CHIP_KEYS', () => {
  it('4개 칩 키를 포함한다', () => {
    expect(SOURCE_CHIP_KEYS).toHaveLength(4);
    expect(SOURCE_CHIP_KEYS).toContain('전체');
    expect(SOURCE_CHIP_KEYS).toContain('약관');
    expect(SOURCE_CHIP_KEYS).toContain('전문가');
    expect(SOURCE_CHIP_KEYS).toContain('커뮤니티');
  });
});

describe('SOURCE_TYPE_LABEL', () => {
  it('모든 sourceType에 한글 라벨이 있다', () => {
    expect(SOURCE_TYPE_LABEL['policy_pdf']).toBe('약관 원문');
    expect(SOURCE_TYPE_LABEL['kakao_expert']).toBe('전문가 단톡');
    expect(SOURCE_TYPE_LABEL['youtube']).toBe('유튜브');
  });
});

describe('VERIFICATION_LABEL', () => {
  it('expert_verified에 전문가 검증 라벨이 있다', () => {
    expect(VERIFICATION_LABEL['expert_verified'].label).toContain('전문가 검증');
  });

  it('unverified에 미검증 라벨이 있다', () => {
    expect(VERIFICATION_LABEL['unverified'].label).toBe('미검증');
  });
});

// ── Phase 2a: 신뢰도 매핑 함수 테스트 ──────────────────────────
import {
  getTrustLevel,
  getTrustBadgeInfo,
  getVerificationVisualState,
  getAutoSeverity,
} from '@/lib/constants';

describe('getTrustLevel', () => {
  // 9개 sourceType별 올바른 level 매핑
  it('policy_pdf → official', () => {
    expect(getTrustLevel(undefined, 'policy_pdf')).toBe('official');
  });

  it('regulation → official', () => {
    expect(getTrustLevel(undefined, 'regulation')).toBe('official');
  });

  it('newsletter → expert', () => {
    expect(getTrustLevel(undefined, 'newsletter')).toBe('expert');
  });

  it('court_ruling → expert', () => {
    expect(getTrustLevel(undefined, 'court_ruling')).toBe('expert');
  });

  it('wiki_editorial → expert', () => {
    expect(getTrustLevel(undefined, 'wiki_editorial')).toBe('expert');
  });

  it('kakao_expert → expert', () => {
    expect(getTrustLevel(undefined, 'kakao_expert')).toBe('expert');
  });

  it('kakao_community → reference', () => {
    expect(getTrustLevel(undefined, 'kakao_community')).toBe('reference');
  });

  it('youtube → reference', () => {
    expect(getTrustLevel(undefined, 'youtube')).toBe('reference');
  });

  it('user_submitted → reference', () => {
    expect(getTrustLevel(undefined, 'user_submitted')).toBe('reference');
  });

  // tier 경계값 테스트
  it('tier 1 → official', () => {
    expect(getTrustLevel(1)).toBe('official');
  });

  it('tier 1.5 → official', () => {
    expect(getTrustLevel(1.5)).toBe('official');
  });

  it('tier 2 → expert', () => {
    expect(getTrustLevel(2)).toBe('expert');
  });

  it('tier 3.5 → expert', () => {
    expect(getTrustLevel(3.5)).toBe('expert');
  });

  it('tier 4 → reference', () => {
    expect(getTrustLevel(4)).toBe('reference');
  });

  // authorityTier 없고 sourceType만 있는 경우 (위에서 이미 검증)
  // 둘 다 없는 경우 → 'reference'
  it('authorityTier와 sourceType 모두 없으면 reference를 반환한다', () => {
    expect(getTrustLevel()).toBe('reference');
    expect(getTrustLevel(undefined, undefined)).toBe('reference');
  });
});

describe('getTrustBadgeInfo', () => {
  it('official → 공식확인, green 계열', () => {
    const info = getTrustBadgeInfo(1);
    expect(info.level).toBe('official');
    expect(info.label).toBe('공식확인');
    expect(info.colorClass).toContain('green');
  });

  it('expert → 전문가검증, blue 계열', () => {
    const info = getTrustBadgeInfo(2);
    expect(info.level).toBe('expert');
    expect(info.label).toBe('전문가검증');
    expect(info.colorClass).toContain('blue');
  });

  it('reference → 참고정보, gray 계열', () => {
    const info = getTrustBadgeInfo(4);
    expect(info.level).toBe('reference');
    expect(info.label).toBe('참고정보');
    expect(info.colorClass).toContain('gray');
  });

  it('인수 없으면 reference(참고정보)를 반환한다', () => {
    const info = getTrustBadgeInfo();
    expect(info.level).toBe('reference');
    expect(info.label).toBe('참고정보');
  });
});

describe('getVerificationVisualState', () => {
  it('documentStatus approved → verified', () => {
    expect(getVerificationVisualState('approved')).toBe('verified');
  });

  it('verificationStatus expert_verified → verified', () => {
    expect(getVerificationVisualState(undefined, 'expert_verified')).toBe('verified');
  });

  it('documentStatus rejected → rejected', () => {
    expect(getVerificationVisualState('rejected')).toBe('rejected');
  });

  it('documentStatus revision_requested → rejected', () => {
    expect(getVerificationVisualState('revision_requested')).toBe('rejected');
  });

  it('documentStatus in_review → in_review', () => {
    expect(getVerificationVisualState('in_review')).toBe('in_review');
  });

  it('documentStatus needs_re_review → in_review', () => {
    expect(getVerificationVisualState('needs_re_review')).toBe('in_review');
  });

  it('documentStatus draft → pending', () => {
    expect(getVerificationVisualState('draft')).toBe('pending');
  });

  it('documentStatus published → pending', () => {
    expect(getVerificationVisualState('published')).toBe('pending');
  });

  it('둘 다 undefined → pending', () => {
    expect(getVerificationVisualState()).toBe('pending');
    expect(getVerificationVisualState(undefined, undefined)).toBe('pending');
  });

  it('documentStatus=in_review, verificationStatus=expert_verified → verified (verificationStatus 우선)', () => {
    expect(getVerificationVisualState('in_review', 'expert_verified')).toBe('verified');
  });

  it('verificationStatus=auto_passed → verified', () => {
    expect(getVerificationVisualState(undefined, 'auto_passed')).toBe('verified');
  });

  it('documentStatus=draft, verificationStatus=auto_passed → verified (auto_passed 우선)', () => {
    expect(getVerificationVisualState('draft', 'auto_passed')).toBe('verified');
  });
});

describe('getAutoSeverity', () => {
  it('practice + user_submitted → caution', () => {
    expect(getAutoSeverity('practice', 'user_submitted')).toBe('caution');
  });

  it('practice + policy_pdf → info', () => {
    expect(getAutoSeverity('practice', 'policy_pdf')).toBe('info');
  });

  it('general + user_submitted → info', () => {
    expect(getAutoSeverity('general', 'user_submitted')).toBe('info');
  });

  it('undefined → info', () => {
    expect(getAutoSeverity()).toBe('info');
    expect(getAutoSeverity(undefined, undefined)).toBe('info');
  });
});
