"""
test_image_workflow_v25.py

image_workflow.py v2.5 변경 사항 검증 테스트 (아르고스 작성)

테스트 항목:
- T1: PIPELINE_TOKENS에 KNOWHOW_PRELOAD_OK, DESIGN_QC_OK 존재
- T2: ESCALATION_RULES에 plan_qc_immediate_pass=12, design_qc_immediate_pass=9
- T3: build_phase_minus1_prompt() - 3개 노하우 파일 경로 포함
- T4: build_phase1_5_prompt() - 담당자 "마아트+로키", "아마테라스" 미포함
- T5: build_phase1_5_prompt() - 항목7 "세계 최고" + 학습 기록 + 즉시 PASS
- T6: build_phase3_5_prompt() - DQ-01~DQ-05 전항목 + 사이클별 임계값
- T7: build_phase3_5_prompt() - 학습 기록 knowhow-design.md + DESIGN_QC_OK 토큰
- T8: build_phase5_prompt() - 종합 검토 + 교차 인사이트 + 3개 노하우 파일
- T9: build_workflow_overview_prompt() - 시작 조건 "제이회장님 승인 필수"
- T10: build_image_workflow_prompt() 라우터 - Phase -1, 3.5, 5 정상 라우팅
- T11: build_image_workflow_prompt() 라우터 - 잘못된 Phase 시 ValueError
- T12: dispatch.py에 이미지/광고 키워드 경고 로직 존재
"""

import os
import sys
from pathlib import Path

import pytest

# 워크스페이스 경로 설정
workspace = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
if str(workspace) not in sys.path:
    sys.path.insert(0, str(workspace))

from prompts.image_workflow import (
    ESCALATION_RULES,
    PIPELINE_TOKENS,
    build_image_workflow_prompt,
    build_phase0_5_prompt,
    build_phase1_5_prompt,
    build_phase3_5_prompt,
    build_phase5_prompt,
    build_phase_minus1_prompt,
    build_workflow_overview_prompt,
)


class TestPipelineTokens:
    """T1: PIPELINE_TOKENS 검증"""

    def test_knowhow_preload_ok_in_tokens(self):
        assert "KNOWHOW_PRELOAD_OK" in PIPELINE_TOKENS

    def test_design_qc_ok_in_tokens(self):
        assert "DESIGN_QC_OK" in PIPELINE_TOKENS

    def test_tokens_order_knowhow_first(self):
        """KNOWHOW_PRELOAD_OK이 BRIEF_QC_OK보다 앞에 위치"""
        idx_knowhow = PIPELINE_TOKENS.index("KNOWHOW_PRELOAD_OK")
        idx_brief = PIPELINE_TOKENS.index("BRIEF_QC_OK")
        assert idx_knowhow < idx_brief


class TestEscalationRules:
    """T2: ESCALATION_RULES 즉시 PASS 규칙"""

    def test_plan_qc_immediate_pass(self):
        assert ESCALATION_RULES["plan_qc_immediate_pass"] == 90

    def test_design_qc_immediate_pass(self):
        assert ESCALATION_RULES["design_qc_immediate_pass"] == 97


class TestPhaseMinus1:
    """T3: build_phase_minus1_prompt()"""

    def test_contains_three_knowhow_files(self):
        result = build_phase_minus1_prompt("test-001")
        assert "design-qc-knowhow.md" in result
        assert "knowhow-marketing.md" in result
        assert "knowhow-design.md" in result

    def test_contains_knowhow_preload_token(self):
        result = build_phase_minus1_prompt("test-001")
        assert "KNOWHOW_PRELOAD_OK" in result

    def test_contains_repeat_warning(self):
        """2차, 3차 위임 시에도 반복 수행 안내 포함"""
        result = build_phase_minus1_prompt("test-001")
        assert "2차" in result or "반복 수행" in result


class TestPhase1_5Assignee:
    """T4: Phase 1.5 담당자 변경"""

    def test_contains_loki(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "로키" in result

    def test_no_amaterasu(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "아마테라스" not in result

    def test_third_party_eval_note(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "3자 평가" in result


class TestPhase1_5Content:
    """T5: Phase 1.5 항목7 + 학습 기록 + 즉시 PASS"""

    def test_item7_world_class(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "세계 최고" in result

    def test_learning_record(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "학습 기록" in result
        assert "knowhow-marketing.md" in result

    def test_immediate_pass_rule(self):
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "90점 이상" in result or "즉시 PASS" in result

    def test_learning_record_three_types(self):
        """실패+성공+체크리스트 3종"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "실패 패턴" in result
        assert "성공 패턴" in result
        assert "체크리스트" in result

    def test_no_cycle_cap_phase1_5(self):
        """Phase 1.5 Cycle 상한 '/3' 표시 제거 확인"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md", cycle=1)
        assert "/3" not in result
        assert "PASS까지 반복" in result

    def test_uniform_threshold_phase1_5(self):
        """Phase 1.5 모든 Cycle 동일 85점 기준 적용"""
        r1 = build_phase1_5_prompt("test-001", "/tmp/draft.md", cycle=1)
        r2 = build_phase1_5_prompt("test-001", "/tmp/draft.md", cycle=2)
        r3 = build_phase1_5_prompt("test-001", "/tmp/draft.md", cycle=3)
        # 모든 Cycle에서 threshold가 85점
        assert "85/100점" in r1
        assert "85/100점" in r2
        assert "85/100점" in r3

    def test_no_conditional_approval_phase1_5(self):
        """Phase 1.5 조건부 승인 제거 확인"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "조건부" not in result


class TestPhase3_5DQItems:
    """T6: Phase 3.5 DQ-01~DQ-05 + 사이클별 임계값"""

    def test_all_dq_items(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        for i in range(1, 11):
            assert f"DQ-{i:02d}" in result, f"DQ-{i:02d} 누락"

    def test_dq_content(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "레퍼런스 재현도" in result
        assert "시각적 계층 구조" in result
        assert "프로 완성도" in result  # "세계 최고" → "프로 완성도"
        assert "피드 차별화" in result
        assert "감정적 임팩트" in result
        assert "여백/레이아웃 밸런스" in result
        assert "색상 가시성/조화" in result
        assert "타이포그래피 품질" in result
        assert "CTA 효과성" in result
        assert "브랜드 일관성" in result

    def test_cycle_thresholds(self):
        """모든 Cycle에서 동일한 93점 기준 적용 확인"""
        r1 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=1)
        r2 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=2)
        r3 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=3)
        assert "93" in r1  # 모든 Cycle 동일 기준
        assert "93" in r2
        assert "93" in r3

    def test_immediate_pass(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "97점 이상" in result or "즉시 PASS" in result

    def test_no_cycle_cap(self):
        """Cycle 상한 '/3' 표시 제거 확인"""
        r1 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=1)
        assert "/3" not in r1
        assert "PASS까지 반복" in r1

    def test_no_escalation_text(self):
        """Cycle 3 미달 시 에스컬레이션 문구 제거 확인 (일반 참조는 유지)"""
        r3 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=3)
        assert "미달 시 에스컬레이션" not in r3
        assert "제이회장님 보고" not in r3

    def test_cycle_beyond_3(self):
        """Cycle 4 이상에서도 정상 동작 확인"""
        r5 = build_phase3_5_prompt("test-001", ["/tmp/img.png"], cycle=5)
        assert "93" in r5
        assert "PASS까지 반복" in r5


class TestPhase3_5Learning:
    """T7: Phase 3.5 학습 기록 + 토큰"""

    def test_learning_record_design(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "학습 기록" in result
        assert "knowhow-design.md" in result

    def test_design_qc_ok_token(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "DESIGN_QC_OK" in result

    def test_assignee_loki_only(self):
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "마아트" not in result
        assert "로키" in result


class TestPhase5:
    """T8: Phase 5 노하우 종합 검토"""

    def test_comprehensive_review(self):
        result = build_phase5_prompt("test-001")
        assert "종합 검토" in result

    def test_cross_insight(self):
        result = build_phase5_prompt("test-001")
        assert "교차 인사이트" in result

    def test_three_knowhow_files(self):
        result = build_phase5_prompt("test-001")
        assert "knowhow-marketing.md" in result
        assert "knowhow-design.md" in result
        assert "design-qc-knowhow.md" in result


class TestWorkflowOverview:
    """T9: 시작 조건"""

    def test_approval_required(self):
        result = build_workflow_overview_prompt("test-001")
        assert "제이회장님 승인 필수" in result

    def test_all_phases_listed(self):
        result = build_workflow_overview_prompt("test-001")
        assert "Phase -1" in result
        assert "Phase 3.5" in result
        assert "Phase 5" in result

    def test_no_3cycle_text(self):
        """'3사이클' 문구가 'PASS까지 반복'으로 변경 확인"""
        result = build_workflow_overview_prompt("test-001")
        assert "3사이클" not in result
        assert "PASS까지 반복" in result


class TestRouterNewPhases:
    """T10: 라우터 Phase -1, 3.5, 5"""

    def test_phase_minus1(self):
        result = build_image_workflow_prompt("test-001", phase=-1)
        assert "Phase -1" in result

    def test_phase_3_5(self):
        result = build_image_workflow_prompt("test-001", phase=3.5, image_paths=["/tmp/a.png"])
        assert "Phase 3.5" in result

    def test_phase_5(self):
        result = build_image_workflow_prompt("test-001", phase=5)
        assert "Phase 5" in result


class TestRouterErrors:
    """T11: 라우터 에러 케이스"""

    def test_invalid_phase_raises(self):
        with pytest.raises(ValueError, match="지원하지 않는 Phase"):
            build_image_workflow_prompt("test-001", phase=99)

    def test_error_message_includes_new_phases(self):
        with pytest.raises(ValueError, match="-1.*3.5.*5"):
            build_image_workflow_prompt("test-001", phase=99)

    def test_phase_3_5_requires_image_paths(self):
        with pytest.raises(ValueError, match="image_paths"):
            build_image_workflow_prompt("test-001", phase=3.5)


class TestDispatchWarning:
    """T12: dispatch.py 경고 로직 존재"""

    def test_warning_logic_exists(self):
        dispatch_path = workspace / "dispatch.py"
        content = dispatch_path.read_text(encoding="utf-8")
        assert "_image_keywords" in content
        assert "이미지/광고 작업에 --workflow image-qc-gate가 필수입니다" in content


class TestFeedbackV26:
    """제이회장님 피드백 4건 반영 검증 (task-1268.1)"""

    def test_a07_wcag_aaa(self):
        """A-07 대비율 기준 WCAG AAA 상향"""
        from prompts.image_workflow import QC_CATEGORY_A

        assert "AAA" in QC_CATEGORY_A["A-07"]["check"]
        assert "7:1" in QC_CATEGORY_A["A-07"]["check"]

    def test_a08_min_40px_no_exception(self):
        """A-08 최소 폰트 40px, 예외 없음"""
        from prompts.image_workflow import QC_CATEGORY_A

        assert "40px" in QC_CATEGORY_A["A-08"]["check"]
        assert "예외 없음" in QC_CATEGORY_A["A-08"]["check"]
        assert "14px" not in QC_CATEGORY_A["A-08"]["check"]

    def test_a09_font_weight_exists(self):
        """A-09 폰트 두께 항목 존재"""
        from prompts.image_workflow import QC_CATEGORY_A

        assert "A-09" in QC_CATEGORY_A
        assert "300" in QC_CATEGORY_A["A-09"]["check"]
        assert "400" in QC_CATEGORY_A["A-09"]["check"]

    def test_font_weight_fail_category(self):
        """FONT_WEIGHT_FAIL 카테고리 추가"""
        from prompts.image_workflow import FAIL_CATEGORIES

        assert "FONT_WEIGHT_FAIL" in FAIL_CATEGORIES

    def test_phase3_font_weight_rule(self):
        """Phase 3 프롬프트에 폰트 두께 규칙 포함"""
        from prompts.image_workflow import build_phase3_prompt

        result = build_phase3_prompt("test-001", "/tmp/plan.md")
        assert "font-weight 300" in result
        assert "A-09" in result

    def test_phase3_wcag_aaa_rule(self):
        """Phase 3 프롬프트에 WCAG AAA 규칙 포함"""
        from prompts.image_workflow import build_phase3_prompt

        result = build_phase3_prompt("test-001", "/tmp/plan.md")
        assert "AAA" in result
        assert "7:1" in result

    def test_phase3_glassmorphism_guide(self):
        """Phase 3 프롬프트에 글래스모피즘 가이드 포함"""
        from prompts.image_workflow import build_phase3_prompt

        result = build_phase3_prompt("test-001", "/tmp/plan.md")
        assert "글래스모피즘" in result
        assert "backdrop-filter" in result
        assert "opacity" in result

    def test_phase3_logo_rule(self):
        """Phase 3 프롬프트에 서울대보험쌤 로고 규칙 포함"""
        from prompts.image_workflow import build_phase3_prompt

        result = build_phase3_prompt("test-001", "/tmp/plan.md")
        assert "logo-snuinsurance" in result
        assert "logo-snuinsurance-white" in result

    def test_phase2_5_40px_reference(self):
        """Phase 2.5 프롬프트 40px 참조"""
        from prompts.image_workflow import build_image_workflow_prompt

        result = build_image_workflow_prompt(
            "test-001",
            phase=2.5,
            pilot_image_paths=["/tmp/pilot1.png", "/tmp/pilot2.png", "/tmp/pilot3.png"],
        )
        assert "40px" in result
        assert "14px" not in result

    def test_phase2_5_aaa_reference(self):
        """Phase 2.5 프롬프트 AAA 참조"""
        from prompts.image_workflow import build_image_workflow_prompt

        result = build_image_workflow_prompt(
            "test-001",
            phase=2.5,
            pilot_image_paths=["/tmp/pilot1.png", "/tmp/pilot2.png", "/tmp/pilot3.png"],
        )
        assert "AAA" in result or "7:1" in result

    def test_phase3_5_a09_reference(self):
        """Phase 3.5 프롬프트에서 A 카테고리 9항목 참조"""
        from prompts.image_workflow import build_phase3_5_prompt

        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "A-09" in result or "9항목" in result


class TestScoreUnification100:
    """QC 점수 체계 100점 만점 통일 검증 (task-1335.1)"""

    def test_phase0_5_total_100(self):
        """Phase 0.5 브리프 QC 100점 만점"""
        from prompts.image_workflow import build_phase0_5_prompt
        result = build_phase0_5_prompt("test-001")
        assert "100점 만점" in result
        assert "85점 이상 통과" in result
        assert "X/20점" in result  # 각 항목 20점
        assert "총점: X/100" in result

    def test_phase0_5_scoring_ranges(self):
        """Phase 0.5 판정 범위 PASS/FAIL 2단계"""
        from prompts.image_workflow import build_phase0_5_prompt
        result = build_phase0_5_prompt("test-001")
        assert "85점 이상" in result
        assert "84점 이하" in result
        assert "조건부" not in result

    def test_phase1_5_total_100(self):
        """Phase 1.5 기획 QC 100점 만점"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "100점 만점" in result
        assert "85/100점" in result  # 통과 임계값
        assert "총점: X/100" in result

    def test_phase0_5_no_conditional(self):
        """Phase 0.5 조건부 승인 제거 확인"""
        from prompts.image_workflow import build_phase0_5_prompt
        result = build_phase0_5_prompt("test-001")
        assert "조건부" not in result

    def test_phase1_5_item_scores(self):
        """Phase 1.5 항목별 배점: 상위 2항목 15점 + 하위 5항목 14점 = 100점"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "PQ-01 | 메시지 계층 구조 | 15점" in result
        assert "PQ-02 | 감정적 훅 존재 | 15점" in result
        assert "PQ-03 | CTA 명시 | 14점" in result
        assert "PQ-07 | 세계 최고 전문가/프로 수준 | 14점" in result

    def test_phase1_5_immediate_pass_90(self):
        """Phase 1.5 즉시 PASS 기준: 90점"""
        result = build_phase1_5_prompt("test-001", "/tmp/draft.md")
        assert "90점 이상 = 즉시 PASS" in result

    def test_phase3_5_unchanged_100(self):
        """Phase 3.5 DQ 10항목 100점 체계 유지 확인"""
        result = build_phase3_5_prompt("test-001", ["/tmp/img.png"])
        assert "DQ-01" in result
        assert "10점" in result
        assert "97점 이상" in result or "즉시 PASS" in result

    def test_escalation_rules_updated(self):
        """ESCALATION_RULES plan_qc_immediate_pass = 90"""
        assert ESCALATION_RULES["plan_qc_immediate_pass"] == 90
        assert ESCALATION_RULES["design_qc_immediate_pass"] == 97  # 변경 없음

    def test_workflow_overview_100(self):
        """워크플로우 오버뷰 100점 표기"""
        result = build_workflow_overview_prompt("test-001")
        assert "5항목 100점" in result
        assert "7항목 100점" in result
