"""
Local Filesystem Storage Backend

For development mode (Termux) - stores files in local directory
"""

import os
from pathlib import Path
from typing import Optional
from loguru import logger

from .base import StorageBackend, StorageError


class LocalStorage(StorageBackend):
    """
    Local filesystem storage implementation

    Stores files in organized directory structure:
    storage/
    ├── ab/
    │   ├── c1/
    │   │   └── abc123...def.sub
    """

    def __init__(self, base_path: str = "./storage"):
        """
        Initialize local storage

        Args:
            base_path: Base directory for file storage
        """
        self.base_path = Path(base_path)

        # Create base directory if it doesn't exist
        self.base_path.mkdir(parents=True, exist_ok=True)

        logger.info(f"LocalStorage initialized at: {self.base_path.absolute()}")

    def save_file(self, file_hash: str, content: bytes, filename: Optional[str] = None) -> str:
        """Save file to local filesystem"""
        try:
            # Get storage path
            relative_path = self.get_file_path(file_hash)
            full_path = self.base_path / relative_path

            # Create parent directories
            full_path.parent.mkdir(parents=True, exist_ok=True)

            # Write file
            with open(full_path, 'wb') as f:
                f.write(content)

            logger.debug(f"File saved: {relative_path} ({len(content)} bytes)")

            return str(relative_path)

        except Exception as e:
            logger.error(f"Failed to save file {file_hash}: {e}")
            raise StorageError(f"Failed to save file: {e}")

    def get_file(self, file_hash: str) -> bytes:
        """Retrieve file from local filesystem"""
        try:
            relative_path = self.get_file_path(file_hash)
            full_path = self.base_path / relative_path

            if not full_path.exists():
                raise FileNotFoundError(f"File not found: {file_hash}")

            with open(full_path, 'rb') as f:
                content = f.read()

            logger.debug(f"File retrieved: {relative_path} ({len(content)} bytes)")

            return content

        except FileNotFoundError:
            raise
        except Exception as e:
            logger.error(f"Failed to retrieve file {file_hash}: {e}")
            raise StorageError(f"Failed to retrieve file: {e}")

    def file_exists(self, file_hash: str) -> bool:
        """Check if file exists"""
        try:
            relative_path = self.get_file_path(file_hash)
            full_path = self.base_path / relative_path
            return full_path.exists()

        except Exception as e:
            logger.error(f"Failed to check file existence {file_hash}: {e}")
            return False

    def delete_file(self, file_hash: str) -> bool:
        """Delete file from filesystem"""
        try:
            relative_path = self.get_file_path(file_hash)
            full_path = self.base_path / relative_path

            if not full_path.exists():
                return False

            full_path.unlink()
            logger.debug(f"File deleted: {relative_path}")

            # Clean up empty parent directories
            try:
                full_path.parent.rmdir()  # Only works if empty
                full_path.parent.parent.rmdir()  # Only works if empty
            except OSError:
                pass  # Directory not empty, that's fine

            return True

        except Exception as e:
            logger.error(f"Failed to delete file {file_hash}: {e}")
            raise StorageError(f"Failed to delete file: {e}")

    def get_file_url(self, file_hash: str) -> str:
        """Get file:// URL for local file"""
        relative_path = self.get_file_path(file_hash)
        full_path = self.base_path / relative_path

        return f"file://{full_path.absolute()}"

    def get_storage_stats(self) -> dict:
        """
        Get storage statistics

        Returns:
            Dictionary with storage stats
        """
        total_files = 0
        total_size = 0

        try:
            for file_path in self.base_path.rglob("*.sub"):
                total_files += 1
                total_size += file_path.stat().st_size

            return {
                "total_files": total_files,
                "total_size_bytes": total_size,
                "total_size_mb": round(total_size / (1024 * 1024), 2),
                "base_path": str(self.base_path.absolute())
            }

        except Exception as e:
            logger.error(f"Failed to get storage stats: {e}")
            return {
                "error": str(e)
            }
