"""
Implementación de Origin para sistema de archivos local.
"""
import os
from pathlib import Path
from typing import List, Optional, TYPE_CHECKING

from tai_alphi import Alphi
from tai_storage.base import Origin
from tai_storage.exceptions import (
    FolderNotFoundError,
    FolderAlreadyExistsError,
    InvalidPathError,
)
from tai_storage.utils import normalize_path, join_paths, match_pattern

if TYPE_CHECKING:
    from .folder import LocalFolder

logger = Alphi.get_logger_by_name('tai-storage')


class LocalOrigin(Origin):
    """
    Implementación de Origin para el sistema de archivos local.
    
    Este origen representa el acceso a archivos y carpetas en el
    sistema de archivos local de la máquina.
    """
    
    def __init__(self, root_path: str):
        """
        Inicializa el origen local.
        
        Args:
            root_path: Ruta raíz del almacenamiento local
            
        Example:
            >>> origin = LocalOrigin(root_path='/home/user/data')
            >>> folder = origin.get_folder('documents')
        """
        super().__init__()
        self.root_path = os.path.abspath(root_path)
        self._root = Path(self.root_path)
        
        logger.info(f"Initialized LocalOrigin with root: {self.root_path}")
        
        # Crear directorio raíz si no existe
        if not self._root.exists():
            logger.info(f"Creating root directory: {self.root_path}")
            self._root.mkdir(parents=True, exist_ok=True)
        
        # Para origen local, siempre está "conectado"
        self._connected = True
    
    def connect(self) -> None:
        """
        Establece conexión con el origen.
        
        Para el sistema local, esta operación verifica que el directorio
        raíz existe y es accesible.
        """
        if not self._root.exists():
            logger.error(f"Root directory does not exist: {self.root_path}")
            raise InvalidPathError(f"Root directory does not exist: {self.root_path}")
        
        if not self._root.is_dir():
            logger.error(f"Root path is not a directory: {self.root_path}")
            raise InvalidPathError(f"Root path is not a directory: {self.root_path}")
        
        self._connected = True
        logger.debug(f"Connected to local origin: {self.root_path}")
    
    def disconnect(self) -> None:
        """
        Cierra la conexión con el origen.
        
        Para el sistema local, esta operación es un no-op.
        """
        self._connected = False
        logger.debug(f"Disconnected from local origin: {self.root_path}")
    
    def is_connected(self) -> bool:
        """Verifica si hay conexión activa."""
        return self._connected and self._root.exists()
    
    def _get_full_path(self, path: str) -> str:
        """
        Obtiene la ruta completa combinando root_path con el path relativo.
        
        Args:
            path: Ruta relativa
            
        Returns:
            Ruta absoluta completa
        """
        normalized = normalize_path(path)
        if not normalized:
            return self.root_path
        return os.path.join(self.root_path, normalized)
    
    def get_folder(self, path: str = '') -> 'LocalFolder':
        """Obtiene una referencia a una carpeta."""
        from .folder import LocalFolder
        
        full_path = self._get_full_path(path)
        logger.debug(f"Getting folder reference: {full_path}")
        return LocalFolder(self, full_path)
    
    def list_folders(self, path: str = '', pattern: Optional[str] = None) -> List['LocalFolder']:
        """Lista las carpetas en una ruta específica como objetos LocalFolder."""
        from .folder import LocalFolder
        
        full_path = self._get_full_path(path)
        folder = LocalFolder(self, full_path)
        
        if not folder.exists():
            raise FolderNotFoundError(f"Folder not found: {full_path}")
        
        # Delegar al método list_folders del folder
        return folder.list_folders(pattern=pattern)
    
    def create_folder(self, path: str, parents: bool = True) -> 'LocalFolder':
        """Crea una carpeta en el origen."""
        from .folder import LocalFolder
        
        full_path = self._get_full_path(path)
        folder = LocalFolder(self, full_path)
        
        if folder.exists():
            raise FolderAlreadyExistsError(f"Folder already exists: {full_path}")
        
        logger.info(f"Creating folder: {full_path} (parents={parents})")
        folder.create(parents=parents)
        
        return folder
    
    def delete_folder(self, path: str, recursive: bool = False) -> None:
        """Elimina una carpeta del origen."""
        from .folder import LocalFolder
        
        full_path = self._get_full_path(path)
        
        # No permitir eliminar el directorio raíz
        if os.path.abspath(full_path) == os.path.abspath(self.root_path):
            raise InvalidPathError("Cannot delete root directory")
        
        folder = LocalFolder(self, full_path)
        
        if not folder.exists():
            raise FolderNotFoundError(f"Folder not found: {full_path}")
        
        logger.warning(f"Deleting folder: {full_path} (recursive={recursive})")
        folder.delete(recursive=recursive)
    
    def folder_exists(self, path: str) -> bool:
        """Verifica si una carpeta existe."""
        from .folder import LocalFolder
        
        full_path = self._get_full_path(path)
        folder = LocalFolder(self, full_path)
        return folder.exists()
    
    def __repr__(self) -> str:
        """Representación string del origen."""
        return f"<LocalOrigin root='{self.root_path}' connected={self.is_connected()}>"
