# -*- coding: utf-8 -*-
"""서버사이드 콘텐츠 API 클라이언트

패키지 추출 공격 방어:
- 템플릿/커맨드가 로컬에 없음
- 서버에서 실시간으로 가져옴
- 라이선스 + 7일 + machine_id 검증 후에만 제공
"""

import os
import json
import requests
from pathlib import Path
from datetime import datetime, timedelta

from .license import get_machine_id

# 클라이언트 버전 (서버에서 검증됨)
CLIENT_VERSION = "1.2.0"

# 콘텐츠 서버 URL
CONTENT_SERVER_URL = os.environ.get(
    "CLOUVEL_CONTENT_SERVER_URL",
    "https://clouvel-license-webhook.vnddns999.workers.dev"
)

# 로컬 캐시 경로 (임시, 24시간만 유효)
CONTENT_CACHE_FILE = Path.home() / ".clouvel-content-cache"
CACHE_VALID_HOURS = 24


def _load_license_info() -> dict:
    """라이선스 파일에서 정보 로드"""
    license_file = Path.home() / ".clouvel-license"
    if not license_file.exists():
        return None

    try:
        return json.loads(license_file.read_text(encoding="utf-8"))
    except Exception:
        return None


def _load_cached_content() -> dict:
    """로컬 캐시에서 콘텐츠 로드 (24시간 유효)"""
    if not CONTENT_CACHE_FILE.exists():
        return None

    try:
        data = json.loads(CONTENT_CACHE_FILE.read_text(encoding="utf-8"))

        # 캐시 유효성 확인
        cached_at = data.get("cached_at")
        if cached_at:
            cached_time = datetime.fromisoformat(cached_at)
            if datetime.now() - cached_time < timedelta(hours=CACHE_VALID_HOURS):
                return data.get("content")

        return None
    except Exception:
        return None


def _save_content_cache(content: dict):
    """콘텐츠 캐시 저장"""
    cache_data = {
        "cached_at": datetime.now().isoformat(),
        "content": content
    }
    CONTENT_CACHE_FILE.write_text(json.dumps(cache_data, ensure_ascii=False), encoding="utf-8")


def fetch_content_bundle() -> dict:
    """서버에서 프리미엄 콘텐츠 번들 가져오기

    Returns:
        {
            "success": True,
            "version": "1.0.0",
            "content": {
                "claude_md": "...",
                "commands": {...},
                "templates": {...},
                "config": {...},
                "settings": {...}
            }
        }

        또는 에러:
        {
            "success": False,
            "error": "에러 코드",
            "message": "에러 메시지"
        }
    """
    # 1. 캐시 확인
    cached = _load_cached_content()
    if cached:
        return {
            "success": True,
            "version": cached.get("version", "cached"),
            "content": cached,
            "cached": True
        }

    # 2. 라이선스 정보 로드
    license_info = _load_license_info()
    if not license_info:
        return {
            "success": False,
            "error": "no_license",
            "message": "라이선스가 활성화되지 않았습니다. activate_license를 먼저 실행하세요."
        }

    license_key = license_info.get("license_key")
    activated_at = license_info.get("activated_at")

    if not license_key:
        return {
            "success": False,
            "error": "invalid_license",
            "message": "라이선스 키를 찾을 수 없습니다."
        }

    if not activated_at:
        return {
            "success": False,
            "error": "no_activation_date",
            "message": "활성화 날짜를 찾을 수 없습니다. 라이선스를 다시 활성화하세요."
        }

    # 3. 머신 ID 확인
    machine_id = license_info.get("machine_id") or get_machine_id()

    # 4. 서버에 요청 (machine_id + client_version 포함)
    try:
        response = requests.post(
            f"{CONTENT_SERVER_URL}/content/bundle",
            json={
                "license_key": license_key,
                "activated_at": activated_at,
                "machine_id": machine_id,
                "client_version": CLIENT_VERSION
            },
            timeout=30
        )

        data = response.json()

        if response.status_code == 200 and data.get("success"):
            # 캐시 저장
            _save_content_cache(data.get("content"))
            return {
                "success": True,
                "version": data.get("version"),
                "content": data.get("content"),
                "cached": False
            }

        # 에러 응답
        return {
            "success": False,
            "error": data.get("error", "unknown"),
            "message": data.get("message", "콘텐츠를 가져올 수 없습니다."),
            "days_remaining": data.get("days_remaining"),
            "unlock_date": data.get("unlock_date")
        }

    except requests.exceptions.Timeout:
        # 타임아웃 시 캐시 시도 (만료되어도)
        if CONTENT_CACHE_FILE.exists():
            try:
                data = json.loads(CONTENT_CACHE_FILE.read_text(encoding="utf-8"))
                content = data.get("content")
                if content:
                    return {
                        "success": True,
                        "version": "cached-offline",
                        "content": content,
                        "cached": True,
                        "offline": True
                    }
            except Exception:
                pass

        return {
            "success": False,
            "error": "timeout",
            "message": "서버 연결 시간 초과. 인터넷 연결을 확인하세요."
        }

    except requests.exceptions.ConnectionError:
        # 연결 실패 시 캐시 시도
        if CONTENT_CACHE_FILE.exists():
            try:
                data = json.loads(CONTENT_CACHE_FILE.read_text(encoding="utf-8"))
                content = data.get("content")
                if content:
                    return {
                        "success": True,
                        "version": "cached-offline",
                        "content": content,
                        "cached": True,
                        "offline": True
                    }
            except Exception:
                pass

        return {
            "success": False,
            "error": "connection_error",
            "message": "서버에 연결할 수 없습니다. 인터넷 연결을 확인하세요."
        }

    except Exception as e:
        return {
            "success": False,
            "error": "unknown",
            "message": f"콘텐츠 로드 오류: {str(e)}"
        }


def fetch_content_manifest() -> dict:
    """서버에서 콘텐츠 목록만 가져오기 (내용 없음)

    7일 잠금 상관없이 목록은 볼 수 있음 (티저 용도)
    """
    license_info = _load_license_info()
    if not license_info:
        return {
            "success": False,
            "error": "no_license",
            "message": "라이선스가 필요합니다."
        }

    license_key = license_info.get("license_key")

    try:
        response = requests.get(
            f"{CONTENT_SERVER_URL}/content/manifest",
            headers={"Authorization": f"Bearer {license_key}"},
            timeout=10
        )

        if response.status_code == 200:
            return {
                "success": True,
                **response.json()
            }

        data = response.json()
        return {
            "success": False,
            "error": data.get("error", "unknown"),
            "message": data.get("message", "목록을 가져올 수 없습니다.")
        }

    except Exception as e:
        return {
            "success": False,
            "error": "request_failed",
            "message": str(e)
        }


def clear_content_cache():
    """콘텐츠 캐시 삭제"""
    if CONTENT_CACHE_FILE.exists():
        CONTENT_CACHE_FILE.unlink()


def get_cache_status() -> dict:
    """캐시 상태 확인"""
    if not CONTENT_CACHE_FILE.exists():
        return {"cached": False}

    try:
        data = json.loads(CONTENT_CACHE_FILE.read_text(encoding="utf-8"))
        cached_at = data.get("cached_at")
        if cached_at:
            cached_time = datetime.fromisoformat(cached_at)
            age_hours = (datetime.now() - cached_time).total_seconds() / 3600
            return {
                "cached": True,
                "cached_at": cached_at,
                "age_hours": round(age_hours, 1),
                "valid": age_hours < CACHE_VALID_HOURS
            }
    except Exception:
        pass

    return {"cached": False}
