#!/usr/bin/env python3
"""
tech-debt.py - 기술부채 트래커

Usage:
    python3 scripts/tech-debt.py add --title "제목" --severity high|medium|low [--desc "설명"]
    python3 scripts/tech-debt.py list [--status open|resolved] [--severity high|medium|low]
    python3 scripts/tech-debt.py resolve <id>
    python3 scripts/tech-debt.py show <id>
    python3 scripts/tech-debt.py stats
    python3 scripts/tech-debt.py --help

Features:
    - 기술부채 항목 추가/조회/해결
    - memory/tech-debt.json에 저장
    - 각 항목: id, title, severity, status, created_at, resolved_at
"""

import argparse
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Optional

# 기본 경로
WORKSPACE_ROOT = Path(__file__).parent.parent
DATA_FILE = WORKSPACE_ROOT / "memory" / "tech-debt.json"

# 심각도 레벨
SEVERITY_LEVELS = {
    "high": {"emoji": "🔴", "weight": 3, "label": "높음"},
    "medium": {"emoji": "🟡", "weight": 2, "label": "중간"},
    "low": {"emoji": "🟢", "weight": 1, "label": "낮음"},
}

# 상태
STATUS_OPTIONS = {"open": {"emoji": "🔓", "label": "미해결"}, "resolved": {"emoji": "✅", "label": "해결됨"}}


def load_data() -> dict:
    """tech-debt.json 로드"""
    if not DATA_FILE.exists():
        return {
            "version": "1.0",
            "items": [],
            "metadata": {
                "created": datetime.now().strftime("%Y-%m-%d"),
                "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            },
        }

    with open(DATA_FILE, "r", encoding="utf-8") as f:
        return json.load(f)


def save_data(data: dict) -> None:
    """tech-debt.json 저장"""
    data["metadata"]["last_updated"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 통계 업데이트
    items = data.get("items", [])
    data["metadata"]["stats"] = {
        "total": len(items),
        "open": sum(1 for i in items if i.get("status") == "open"),
        "resolved": sum(1 for i in items if i.get("status") == "resolved"),
        "high_open": sum(1 for i in items if i.get("status") == "open" and i.get("severity") == "high"),
        "medium_open": sum(1 for i in items if i.get("status") == "open" and i.get("severity") == "medium"),
        "low_open": sum(1 for i in items if i.get("status") == "open" and i.get("severity") == "low"),
    }

    DATA_FILE.parent.mkdir(parents=True, exist_ok=True)
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def generate_id() -> str:
    """고유 ID 생성 (TD-001 형식)"""
    data = load_data()
    items = data.get("items", [])

    if not items:
        return "TD-001"

    # 기존 ID 중 최대값 찾기
    max_num = 0
    for item in items:
        try:
            num = int(item.get("id", "TD-000").replace("TD-", ""))
            max_num = max(max_num, num)
        except ValueError:
            continue

    return f"TD-{max_num + 1:03d}"


def add_item(title: str, severity: str, description: str = None, tags: list = None) -> dict:
    """기술부채 항목 추가"""
    data = load_data()

    item_id = generate_id()

    item = {
        "id": item_id,
        "title": title,
        "severity": severity,
        "status": "open",
        "description": description,
        "tags": tags or [],
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "resolved_at": None,
        "resolution_note": None,
    }

    data["items"].append(item)
    save_data(data)

    return item


def list_items(status: str = None, severity: str = None) -> list:
    """기술부채 항목 목록 조회"""
    data = load_data()
    items = data.get("items", [])

    # 필터링
    if status:
        items = [i for i in items if i.get("status") == status]
    if severity:
        items = [i for i in items if i.get("severity") == severity]

    # 심각도 순으로 정렬 (high > medium > low)
    severity_order = {"high": 0, "medium": 1, "low": 2}
    items.sort(key=lambda x: (x.get("status") == "resolved", severity_order.get(x.get("severity"), 3)))

    return items


def resolve_item(item_id: str, resolution_note: str = None) -> Optional[dict]:
    """기술부채 항목 해결"""
    data = load_data()
    items = data.get("items", [])

    for item in items:
        if item.get("id") == item_id:
            if item.get("status") == "resolved":
                print(f"⚠️ 이미 해결된 항목입니다: {item_id}")
                return None

            item["status"] = "resolved"
            item["resolved_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            item["resolution_note"] = resolution_note

            save_data(data)
            return item

    print(f"❌ 항목을 찾을 수 없습니다: {item_id}")
    return None


def show_item(item_id: str) -> Optional[dict]:
    """특정 항목 상세 조회"""
    data = load_data()
    items = data.get("items", [])

    for item in items:
        if item.get("id") == item_id:
            return item

    return None


def show_stats() -> dict:
    """통계 출력"""
    data = load_data()
    metadata = data.get("metadata", {})
    stats = metadata.get("stats", {})

    return {
        "total": stats.get("total", 0),
        "open": stats.get("open", 0),
        "resolved": stats.get("resolved", 0),
        "high_open": stats.get("high_open", 0),
        "medium_open": stats.get("medium_open", 0),
        "low_open": stats.get("low_open", 0),
        "last_updated": metadata.get("last_updated", "-"),
    }


def print_item_table(items: list) -> None:
    """항목 목록을 테이블 형식으로 출력"""
    if not items:
        print("등록된 항목이 없습니다.")
        return

    print("\n📋 기술부채 목록")
    print("=" * 80)
    print(f"{'ID':<10} {'상태':<10} {'심각도':<10} {'제목':<40}")
    print("-" * 80)

    for item in items:
        status_info = STATUS_OPTIONS.get(item.get("status", "open"), {"emoji": "❓", "label": "?"})
        severity_info = SEVERITY_LEVELS.get(item.get("severity", "low"), {"emoji": "⚪", "label": "?"})

        status_str = f"{status_info['emoji']} {status_info['label']}"
        severity_str = f"{severity_info['emoji']} {severity_info['label']}"
        title = item.get("title", "-")[:38]

        print(f"{item.get('id', '-'):<10} {status_str:<10} {severity_str:<10} {title:<40}")

    print("=" * 80)


def print_item_detail(item: dict) -> None:
    """항목 상세 출력"""
    status_info = STATUS_OPTIONS.get(item.get("status", "open"), {"emoji": "❓", "label": "?"})
    severity_info = SEVERITY_LEVELS.get(item.get("severity", "low"), {"emoji": "⚪", "label": "?"})

    print(f"\n{'='*60}")
    print(f"📋 {item.get('id', '-')}: {item.get('title', '-')}")
    print(f"{'='*60}")
    print(f"상태: {status_info['emoji']} {status_info['label']}")
    print(f"심각도: {severity_info['emoji']} {severity_info['label']}")
    print(f"생성일: {item.get('created_at', '-')}")

    if item.get("resolved_at"):
        print(f"해결일: {item.get('resolved_at')}")
    if item.get("resolution_note"):
        print(f"해결 메모: {item.get('resolution_note')}")
    if item.get("description"):
        print(f"\n설명:\n{item.get('description')}")
    if item.get("tags"):
        print(f"\n태그: {', '.join(item.get('tags', []))}")

    print(f"{'='*60}\n")


def main():
    parser = argparse.ArgumentParser(
        description="기술부채 트래커",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
예시:
  python3 scripts/tech-debt.py add --title "레거시 코드 리팩토링" --severity high
  python3 scripts/tech-debt.py list --status open
  python3 scripts/tech-debt.py resolve TD-001 --note "리팩토링 완료"
  python3 scripts/tech-debt.py show TD-001
  python3 scripts/tech-debt.py stats
        """,
    )

    subparsers = parser.add_subparsers(dest="command", help="명령어")

    # add 명령어
    add_parser = subparsers.add_parser("add", help="기술부채 항목 추가")
    add_parser.add_argument("--title", "-t", required=True, help="항목 제목")
    add_parser.add_argument("--severity", "-s", required=True, choices=["high", "medium", "low"], help="심각도")
    add_parser.add_argument("--desc", "-d", default=None, help="상세 설명")
    add_parser.add_argument("--tags", nargs="+", default=[], help="태그")

    # list 명령어
    list_parser = subparsers.add_parser("list", help="항목 목록 조회")
    list_parser.add_argument("--status", choices=["open", "resolved"], default=None, help="상태 필터")
    list_parser.add_argument("--severity", choices=["high", "medium", "low"], default=None, help="심각도 필터")

    # resolve 명령어
    resolve_parser = subparsers.add_parser("resolve", help="항목 해결")
    resolve_parser.add_argument("id", help="항목 ID")
    resolve_parser.add_argument("--note", "-n", default=None, help="해결 메모")

    # show 명령어
    show_parser = subparsers.add_parser("show", help="항목 상세 조회")
    show_parser.add_argument("id", help="항목 ID")

    # stats 명령어
    subparsers.add_parser("stats", help="통계 조회")

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        sys.exit(1)

    if args.command == "add":
        item = add_item(title=args.title, severity=args.severity, description=args.desc, tags=args.tags)
        severity_info = SEVERITY_LEVELS.get(item["severity"], {"emoji": "⚪"})
        print(f"✅ 기술부채 항목 추가 완료!")
        print(f"   ID: {item['id']}")
        print(f"   제목: {item['title']}")
        print(f"   심각도: {severity_info['emoji']} {item['severity']}")

    elif args.command == "list":
        items = list_items(status=args.status, severity=args.severity)
        print_item_table(items)

    elif args.command == "resolve":
        item = resolve_item(args.id, resolution_note=args.note)
        if item:
            print(f"✅ 항목 해결 완료: {args.id}")
            print(f"   제목: {item['title']}")
            print(f"   해결일: {item['resolved_at']}")

    elif args.command == "show":
        item = show_item(args.id)
        if item:
            print_item_detail(item)
        else:
            print(f"❌ 항목을 찾을 수 없습니다: {args.id}")
            sys.exit(1)

    elif args.command == "stats":
        stats = show_stats()
        print("\n📊 기술부채 통계")
        print("=" * 40)
        print(f"총 항목: {stats['total']}개")
        print(f"미해결: {stats['open']}개")
        print(f"  🔴 높음: {stats['high_open']}개")
        print(f"  🟡 중간: {stats['medium_open']}개")
        print(f"  🟢 낮음: {stats['low_open']}개")
        print(f"해결됨: {stats['resolved']}개")
        print("=" * 40)
        print(f"마지막 업데이트: {stats['last_updated']}")


if __name__ == "__main__":
    main()
