"""
Automatic secrets synchronization service.

Single Responsibility: Sync CloudZero API tokens from ~/.czbg/.env to AWS Secrets Manager.
"""

import os
from pathlib import Path

import boto3
from rich.console import Console

console = Console()


class SecretsSyncService:
    """
    Syncs CloudZero API tokens to AWS Secrets Manager.

    Reads tokens from ~/.czbg/.env and updates Secrets Manager.
    Transparent to users - no manual sync needed.
    """

    def __init__(
        self,
        env_file: Path | None = None,
        environment: str = "dev",
        region: str = "us-east-1",
    ):
        """
        Initialize secrets sync service.

        Args:
            env_file: Path to .env file (default: ~/.czbg/.env)
            environment: Environment name (dev, staging, prod)
            region: AWS region for Secrets Manager
        """
        self.env_file = env_file or Path.home() / ".czbg" / ".env"
        self.environment = environment
        self.region = region
        self.secrets_client = boto3.client("secretsmanager", region_name=region)

    def sync_secrets(self, skip_if_worker: bool = True) -> dict[str, str]:
        """
        Sync all CloudZero API tokens to Secrets Manager.

        Args:
            skip_if_worker: Skip sync if running in ECS worker (default: True)

        Returns:
            Dict of synced secrets {org_name: status}
        """
        if skip_if_worker and self._is_running_in_worker():
            return {}

        if not self.env_file.exists():
            console.print(
                f"[yellow]Warning: .env file not found: {self.env_file}[/yellow]"
            )
            return {}

        tokens = self._parse_tokens_from_env()
        if not tokens:
            return {}

        return self._sync_tokens_to_secrets_manager(tokens)

    def _is_running_in_worker(self) -> bool:
        """Check if running in ECS worker environment."""
        return os.getenv("ENVIRONMENT") in ["dev", "staging", "prod"]

    def _parse_tokens_from_env(self) -> dict[str, str]:
        """Parse CloudZero API tokens from .env file."""
        tokens = {}

        with open(self.env_file) as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith("#"):
                    continue

                if "=" not in line:
                    continue

                key, value = line.split("=", 1)
                key = key.strip()
                value = value.strip().strip('"').strip("'")

                if key.startswith("CZ_ORG_API_KEY_"):
                    org_name = key.replace("CZ_ORG_API_KEY_", "")
                    if value:
                        tokens[org_name] = value

        return tokens

    def _sync_tokens_to_secrets_manager(
        self, tokens: dict[str, str]
    ) -> dict[str, str]:
        """Sync tokens to AWS Secrets Manager."""
        results = {}

        for org_name, token_value in tokens.items():
            try:
                result = self._create_or_update_secret(org_name, token_value)
                results[org_name] = result
            except Exception as e:
                console.print(
                    f"[yellow]Warning: Failed to sync {org_name}: {e}[/yellow]"
                )
                results[org_name] = "failed"

        return results

    def _create_or_update_secret(self, org_name: str, token_value: str) -> str:
        """Create or update a single secret."""
        secret_name = f"czbg/{self.environment}/cloudzero/{org_name}"

        try:
            self.secrets_client.create_secret(
                Name=secret_name,
                Description=f"CloudZero API token for {org_name} ({self.environment})",
                SecretString=token_value,
                Tags=[
                    {"Key": "Environment", "Value": self.environment},
                    {"Key": "Organization", "Value": org_name},
                ],
            )
            return "created"
        except self.secrets_client.exceptions.ResourceExistsException:
            self.secrets_client.update_secret(
                SecretId=secret_name,
                SecretString=token_value,
            )
            return "updated"
