"""
Gitea-specific configuration management.
"""

import os
import subprocess
from pathlib import Path
from dataclasses import dataclass
from typing import Optional
from urllib.parse import urlparse

from .exceptions import GiteaConfigError


def load_dotenv_file(env_file: Path) -> None:
    """Load environment variables from a .env file."""
    if not env_file.exists():
        return

    with open(env_file, 'r') as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith('#') and '=' in line:
                key, value = line.split('=', 1)
                os.environ.setdefault(key.strip(), value.strip())


@dataclass
class GiteaConfig:
    """Configuration for Gitea API access."""

    # Repository settings (required)
    gitea_url: str = ""
    repo_owner: str = ""
    repo_name: str = ""

    # Authentication (optional for read operations)
    auth_token: Optional[str] = None

    @property
    def base_api_url(self) -> str:
        """Get the base API URL for this repository."""
        return f"{self.gitea_url}/api/v1"

    @property
    def repo_api_url(self) -> str:
        """Get the repository API URL."""
        return f"{self.base_api_url}/repos/{self.repo_owner}/{self.repo_name}"

    @property
    def issues_api_url(self) -> str:
        """Get the issues API URL."""
        return f"{self.repo_api_url}/issues"

    @property
    def milestones_api_url(self) -> str:
        """Get the milestones API URL."""
        return f"{self.repo_api_url}/milestones"

    @property
    def labels_api_url(self) -> str:
        """Get the labels API URL."""
        return f"{self.repo_api_url}/labels"

    @classmethod
    def from_environment(cls, env_prefix: str = "GITEA") -> "GiteaConfig":
        """Create config from environment variables.

        Args:
            env_prefix: Environment variable prefix (default: GITEA)
                       Looks for {prefix}_URL, {prefix}_REPO_OWNER, etc.
        """
        # Auto-load .env.gitea file if it exists
        env_file = Path(".env.gitea")
        load_dotenv_file(env_file)

        config = cls()

        # Load from environment
        config.gitea_url = os.getenv(f"{env_prefix}_URL", "")
        config.repo_owner = os.getenv(f"{env_prefix}_REPO_OWNER", "")
        config.repo_name = os.getenv(f"{env_prefix}_REPO_NAME", "")
        config.auth_token = os.getenv(f"{env_prefix}_API_TOKEN")

        return config

    @classmethod
    def from_git_repository(cls) -> "GiteaConfig":
        """Create config by auto-detecting from current git repository.

        Only requires GITEA_API_TOKEN environment variable.
        All other settings are detected from git remote origin.
        """
        try:
            # Get git remote origin URL
            result = subprocess.run(
                ['git', 'remote', 'get-url', 'origin'],
                capture_output=True,
                text=True,
                check=True
            )
            origin_url = result.stdout.strip()

            # Parse different URL formats
            if origin_url.startswith('http://') or origin_url.startswith('https://'):
                # HTTP(S) format: https://gitea.example.com/owner/repo.git
                parsed = urlparse(origin_url)
                gitea_url = f"{parsed.scheme}://{parsed.netloc}"
                path_parts = parsed.path.strip('/').split('/')
                if len(path_parts) >= 2:
                    repo_owner = path_parts[0]
                    repo_name = path_parts[1].replace('.git', '')
                else:
                    raise GiteaConfigError(f"Cannot parse repository path from URL: {origin_url}")
            elif '@' in origin_url:
                # SSH format: git@gitea.example.com:owner/repo.git
                if ':' in origin_url:
                    host_part, path_part = origin_url.split(':', 1)
                    host = host_part.split('@')[-1]
                    gitea_url = f"https://{host}"  # Assume HTTPS for API
                    path_parts = path_part.strip('/').split('/')
                    if len(path_parts) >= 2:
                        repo_owner = path_parts[0]
                        repo_name = path_parts[1].replace('.git', '')
                    else:
                        raise GiteaConfigError(f"Cannot parse repository path from SSH URL: {origin_url}")
                else:
                    raise GiteaConfigError(f"Cannot parse SSH URL format: {origin_url}")
            else:
                raise GiteaConfigError(f"Unsupported git remote URL format: {origin_url}")

            # Get auth token from environment
            auth_token = os.getenv('GITEA_API_TOKEN')

            return cls(
                gitea_url=gitea_url,
                repo_owner=repo_owner,
                repo_name=repo_name,
                auth_token=auth_token
            )

        except subprocess.CalledProcessError as e:
            raise GiteaConfigError(f"Failed to get git remote origin: {e}")
        except Exception as e:
            raise GiteaConfigError(f"Failed to auto-detect git repository config: {e}")

    @classmethod
    def from_tddai_config(cls, tddai_config) -> "GiteaConfig":
        """Create GiteaConfig from legacy TddaiConfig for backwards compatibility."""
        return cls(
            gitea_url=tddai_config.gitea_url,
            repo_owner=tddai_config.repo_owner,
            repo_name=tddai_config.repo_name,
            auth_token=os.getenv('GITEA_API_TOKEN')
        )

    def validate(self) -> None:
        """Validate configuration settings."""
        if not self.gitea_url:
            raise GiteaConfigError("gitea_url cannot be empty")

        if not self.repo_owner:
            raise GiteaConfigError("repo_owner cannot be empty")

        if not self.repo_name:
            raise GiteaConfigError("repo_name cannot be empty")

        # Validate URL format
        if not (self.gitea_url.startswith('http://') or self.gitea_url.startswith('https://')):
            raise GiteaConfigError("gitea_url must start with http:// or https://")

    def requires_auth(self, operation: str = "read") -> bool:
        """Check if operation requires authentication."""
        write_operations = {"create", "update", "delete", "write"}
        return operation in write_operations and not self.auth_token
