"""Authentication management for KITECH Repository."""

import json
import os
import stat
from datetime import datetime

from kitech_repository.core.config import Config


class AuthManager:
    """Manage authentication for KITECH Repository using JSON file storage."""

    def __init__(self, config: Config | None = None):
        """Initialize authentication manager."""
        self.config = config or Config.load()
        self.auth_file = self.config.config_dir / "auth.json"
        self.metadata_file = self.config.config_dir / "auth_metadata.json"  # Kept for backward compatibility

    def _save_auth(self, auth_data: dict) -> None:
        """Save authentication data to file with restricted permissions."""
        self.config.config_dir.mkdir(parents=True, exist_ok=True)

        # Write auth data
        self.auth_file.write_text(json.dumps(auth_data, indent=2))

        # Set file permissions to 600 (owner read/write only) for security
        try:
            os.chmod(self.auth_file, stat.S_IRUSR | stat.S_IWUSR)
        except Exception:
            # On Windows, chmod might not work as expected, just continue
            pass

    def _load_auth(self) -> dict:
        """Load authentication data from file."""
        if self.auth_file.exists():
            return json.loads(self.auth_file.read_text())
        # Backward compatibility: try old metadata file
        elif self.metadata_file.exists():
            return json.loads(self.metadata_file.read_text())
        return {}

    def _save_metadata(self, metadata: dict) -> None:
        """Save metadata (deprecated, kept for backward compatibility)."""
        self.config.config_dir.mkdir(parents=True, exist_ok=True)
        self.metadata_file.write_text(json.dumps(metadata, indent=2))

    def _load_metadata(self) -> dict:
        """Load metadata (deprecated, kept for backward compatibility)."""
        if self.metadata_file.exists():
            return json.loads(self.metadata_file.read_text())
        return {}

    def login(self, app_key: str, user_id: str = None, expires_at: str = None) -> bool:
        """Save authentication app key to JSON file.

        ⚠️  Security Warning: App key is stored in plain text at ~/.kitech/auth.json
        For production use, consider using environment variables (KITECH_APP_KEY)
        """
        if not app_key.startswith("kt_"):
            raise ValueError("잘못된 App Key 형식입니다. App Key는 'kt_'로 시작해야 합니다")

        try:
            # Store app key and metadata in JSON file
            auth_data = {
                "app_key": app_key,
                "user_id": user_id,
                "created_at": datetime.now().isoformat(),
                "expires_at": expires_at,
            }
            self._save_auth(auth_data)

            return True
        except Exception as e:
            raise RuntimeError(f"인증 정보 저장 실패: {e}") from e

    def logout(self) -> bool:
        """Remove authentication app key from JSON file."""
        try:
            # Remove auth file
            if self.auth_file.exists():
                self.auth_file.unlink()

            # Remove old metadata file (backward compatibility)
            if self.metadata_file.exists():
                self.metadata_file.unlink()

            return True
        except Exception as e:
            raise RuntimeError(f"인증 정보 제거 실패: {e}") from e

    def get_app_key(self) -> str | None:
        """Get the stored authentication app key from JSON file."""
        try:
            auth_data = self._load_auth()
            return auth_data.get("app_key")
        except Exception:
            return None

    def is_authenticated(self) -> bool:
        """Check if user is authenticated and app key is not expired."""
        # Check if key exists
        app_key = self.get_app_key()
        if not app_key:
            return False

        # Check expiry if available
        auth_data = self._load_auth()
        expires_at = auth_data.get("expires_at")
        if expires_at:
            try:
                expiry = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
                if datetime.now() > expiry:
                    return False
            except (ValueError, TypeError):
                # Invalid expiry format, ignore
                pass

        return True

    @property
    def headers(self) -> dict:
        """Get authentication headers for API requests."""
        app_key = self.get_app_key()
        if not app_key:
            raise ValueError("인증되지 않았습니다. 먼저 로그인해주세요.")

        return {
            "X-App-Key": app_key,
            "accept": "*/*",
        }
