"""대시보드 Todo 탭 전환 기능 테스트 (task-871.1)

Playwright를 사용하여 데스크탑 + 모바일 뷰포트에서 탭 전환 기능을 검증합니다.
"""

import asyncio
import os
import subprocess
from pathlib import Path

import pytest

_WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))


class TestTodoTabSwitching:
    """Todo 탭 전환 기능 테스트."""

    @pytest.fixture(autouse=True)
    def setup_server(self):
        """서버 실행 확인."""
        result = subprocess.run(
            ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "http://localhost:8000/dashboard/"],
            capture_output=True,
            text=True,
        )
        if result.stdout != "200":
            pytest.skip("Dashboard server not running on port 8000")

    @pytest.mark.asyncio
    async def test_desktop_tab_switching(self) -> None:
        """데스크탑 뷰포트에서 탭 전환 테스트."""
        from playwright.async_api import async_playwright

        async with async_playwright() as p:
            browser = await p.chromium.launch()
            page = await browser.new_page(viewport={"width": 1280, "height": 800})

            await page.goto("http://localhost:8000/dashboard/", wait_until="load")
            await asyncio.sleep(3)

            # 프로젝트뷰 탭 클릭
            await page.click('button:has-text("프로젝트")')
            await asyncio.sleep(1)

            # 완료 탭 클릭
            done_button = page.locator('button:has-text("완료")')
            await done_button.click()
            await asyncio.sleep(1)

            # 전체 탭 클릭
            all_button = page.get_by_role("button", name="전체", exact=True)
            await all_button.click()
            await asyncio.sleep(1)

            # 진행중 탭 클릭
            active_button = page.locator('button:has-text("진행중")')
            await active_button.click()
            await asyncio.sleep(1)

            await browser.close()

    @pytest.mark.asyncio
    async def test_mobile_tab_switching(self) -> None:
        """모바일 뷰포트에서 탭 전환 테스트."""
        from playwright.async_api import async_playwright

        async with async_playwright() as p:
            browser = await p.chromium.launch()
            page = await browser.new_page(viewport={"width": 375, "height": 812})

            await page.goto("http://localhost:8000/dashboard/", wait_until="load")
            await asyncio.sleep(3)

            # 프로젝트뷰 탭 클릭
            await page.click('button:has-text("프로젝트")')
            await asyncio.sleep(1)

            # 완료 탭 클릭
            done_button = page.locator('button:has-text("완료")')
            await done_button.click()
            await asyncio.sleep(1)

            # 전체 탭 클릭
            all_button = page.get_by_role("button", name="전체", exact=True)
            await all_button.click()
            await asyncio.sleep(1)

            await browser.close()

    def test_api_status_all(self) -> None:
        """API가 전체 이슈를 반환하는지 테스트."""
        result = subprocess.run(
            ["curl", "-s", "http://localhost:8000/api/todo?status=all"],
            capture_output=True,
            text=True,
        )
        import json

        data = json.loads(result.stdout)
        issues = data.get("issues", [])
        assert len(issues) > 0, "전체 이슈가 0건이면 안 됨"

    def test_api_status_done(self) -> None:
        """API가 완료 이슈만 반환하는지 테스트."""
        result = subprocess.run(
            ["curl", "-s", "http://localhost:8000/api/todo?status=done"],
            capture_output=True,
            text=True,
        )
        import json

        data = json.loads(result.stdout)
        issues = data.get("issues", [])
        assert len(issues) >= 0, "완료 이슈 목록이어야 함"
        for issue in issues:
            assert issue.get("status") in ("done", "completed")

    def test_api_status_default(self) -> None:
        """API가 기본적으로 active 이슈만 반환하는지 테스트."""
        result = subprocess.run(
            ["curl", "-s", "http://localhost:8000/api/todo"],
            capture_output=True,
            text=True,
        )
        import json

        data = json.loads(result.stdout)
        issues = data.get("issues", [])
        assert len(issues) > 0, "활성 이슈가 0건이면 안 됨"
        for issue in issues:
            assert issue.get("status") not in ("done", "completed")

    def test_api_status_counts_consistent(self) -> None:
        """전체 이슈 = 활성 이슈 + 완료 이슈 수학적 일관성 검증."""
        import json

        # all
        r_all = subprocess.run(
            ["curl", "-s", "http://localhost:8000/api/todo?status=all"], capture_output=True, text=True
        )
        all_count = len(json.loads(r_all.stdout).get("issues", []))
        # done
        r_done = subprocess.run(
            ["curl", "-s", "http://localhost:8000/api/todo?status=done"], capture_output=True, text=True
        )
        done_count = len(json.loads(r_done.stdout).get("issues", []))
        # active (default)
        r_active = subprocess.run(["curl", "-s", "http://localhost:8000/api/todo"], capture_output=True, text=True)
        active_count = len(json.loads(r_active.stdout).get("issues", []))
        assert all_count == active_count + done_count, f"전체({all_count}) != 활성({active_count}) + 완료({done_count})"


class TestButtonStyles:
    """버튼 스타일 테스트."""

    @pytest.mark.asyncio
    async def test_button_cursor_pointer(self) -> None:
        """버튼에 cursor-pointer 클래스가 있는지 테스트."""
        from playwright.async_api import async_playwright

        async with async_playwright() as p:
            browser = await p.chromium.launch()
            page = await browser.new_page(viewport={"width": 1280, "height": 800})

            await page.goto("http://localhost:8000/dashboard/", wait_until="load")
            await asyncio.sleep(3)

            # 프로젝트뷰 탭 클릭
            await page.click('button:has-text("프로젝트")')
            await asyncio.sleep(1)

            # 완료 버튼의 스타일 확인
            done_button = page.locator('button:has-text("완료")')
            class_name = await done_button.get_attribute("class")
            assert class_name is not None, "Button has no class attribute"
            assert "cursor-pointer" in class_name, f"Expected cursor-pointer in class, got: {class_name}"

            await browser.close()

    @pytest.mark.asyncio
    async def test_button_min_height(self) -> None:
        """버튼에 최소 높이가 있는지 테스트."""
        from playwright.async_api import async_playwright

        async with async_playwright() as p:
            browser = await p.chromium.launch()
            page = await browser.new_page(viewport={"width": 1280, "height": 800})

            await page.goto("http://localhost:8000/dashboard/", wait_until="load")
            await asyncio.sleep(3)

            # 프로젝트뷰 탭 클릭
            await page.click('button:has-text("프로젝트")')
            await asyncio.sleep(1)

            # 완료 버튼의 스타일 확인
            done_button = page.locator('button:has-text("완료")')
            class_name = await done_button.get_attribute("class")
            assert class_name is not None, "Button has no class attribute"
            assert "min-h" in class_name, f"Expected min-h in class, got: {class_name}"

            await browser.close()


class TestServiceWorkerCache:
    """Service Worker 캐시 테스트."""

    def test_cache_version_updated(self) -> None:
        """Service Worker 캐시 버전이 올바른 형식인지 테스트."""
        with open(_WORKSPACE / "dashboard" / "sw.js", encoding="utf-8") as f:
            content = f.read()
        # 정확한 버전 번호 대신 "dashboard-v" 접두사 패턴 검증
        import re

        assert re.search(r"dashboard-v\d+", content), "CACHE_NAME이 dashboard-vN 패턴이어야 함"
