import io
import uuid
import os
import logging
import json
import shutil
from io import BytesIO
from fastapi import UploadFile
from pydantic_settings import BaseSettings
from pydantic import Field
from fastapi import HTTPException
import urllib.parse
from typing import Optional

logger = logging.getLogger('adimsayar')

class Settings(BaseSettings):
    # 로컬 스토리지 설정
    STORAGE_BASE_PATH: str = Field("/var/www/adimsayar.easerver.net/htdocs/storage", env="STORAGE_BASE_PATH")
    BASE_URL: str = Field("https://adimsayar.easerver.net", env="BASE_URL")

    class Config:
        env_file = ".env"
        case_sensitive = True
        extra = "ignore"

class MediaService:
    def __init__(self, storage_base_path: str, base_url: str):
        """
        로컬 파일 시스템 기반 미디어 서비스를 초기화합니다.
        :param storage_base_path: 스토리지 기본 경로 (예: "/var/www/adimsayar.easerver.net/htdocs/storage")
        :param base_url: 서비스 기본 URL (예: "https://adimsayar.easerver.net")
        """
        self.storage_base_path = storage_base_path
        self.base_url = base_url
        logger.info(f"MediaService initialized with local storage path: {storage_base_path}")
        
        # 필요한 디렉토리 생성
        self._ensure_directories()

    def _ensure_directories(self):
        """기본 디렉토리 구조를 생성합니다."""
        for directory in ["profile", "product"]:
            path = os.path.join(self.storage_base_path, directory)
            if not os.path.exists(path):
                os.makedirs(path, exist_ok=True)
                logger.info(f"Created directory: {path}")
    
    def upload_file(self, file: UploadFile, filename: str) -> str:
        """
        파일을 업로드합니다. 
        :param file: 업로드할 파일
        :param filename: 저장할 파일명 (경로 포함)
        :return: 접근 가능한 URL
        """
        full_path = os.path.join(self.storage_base_path, filename)
        
        # 디버깅 로그 추가
        logger.info(f"upload_file called with filename: {filename}")
        logger.info(f"Full path for file storage: {full_path}")
        
        # 디렉토리 확인 및 생성
        directory = os.path.dirname(full_path)
        logger.info(f"Ensuring directory exists: {directory}")
        os.makedirs(directory, exist_ok=True)
        
        # 파일 저장
        try:
            logger.info(f"Attempting to write file to: {full_path}")
            with open(full_path, "wb") as dest_file:
                content = file.file.read()
                logger.info(f"Read {len(content)} bytes from upload")
                dest_file.write(content)
                file.file.seek(0)  # 파일 포인터 재설정
                logger.info(f"Successfully wrote file to {full_path}")
        except Exception as e:
            logger.error(f"Error uploading file: {str(e)}")
            raise HTTPException(status_code=500, detail=f"File upload failed: {str(e)}")
        
        # URL 생성
        url = f"{self.base_url}/storage/{filename}"
        logger.info(f"File uploaded successfully: {url}")
        return url

    def create_folder(self, folder_name: str):
        """폴더를 생성합니다."""
        folder_path = os.path.join(self.storage_base_path, folder_name)
        if not os.path.exists(folder_path):
            os.makedirs(folder_path, exist_ok=True)
            logger.info(f"Created folder: {folder_path}")
        return folder_path

    def upload_image(self, upload_file: UploadFile, folder: str = "profile") -> str:
        """
        이미지를 업로드합니다.
        :param upload_file: 업로드할 이미지 파일
        :param folder: 저장할 폴더 (기본: "profile")
        :return: 이미지 URL
        """
        # 자세한 디버깅 로그 추가
        logger.info(f"Upload image called with file '{upload_file.filename}' to folder '{folder}'")
        
        # 파일명 생성 및 경로 구성
        original_filename = upload_file.filename
        extension = os.path.splitext(original_filename)[1].lower()
        unique_filename = f"{uuid.uuid4()}{extension}"
        file_path = f"{folder}/{unique_filename}"
        
        logger.info(f"Generated file path: {file_path}")
        logger.info(f"Full storage path will be: {os.path.join(self.storage_base_path, file_path)}")
        
        # 파일 업로드
        return self.upload_file(upload_file, file_path)

    def delete_file(self, file_path: str) -> bool:
        """
        파일을 삭제합니다.
        :param file_path: 삭제할 파일 경로 (URL 또는 상대 경로)
        :return: 성공 여부
        """
        # URL에서 상대 경로 추출
        if file_path.startswith(self.base_url):
            file_path = file_path.replace(f"{self.base_url}/storage/", "")
        
        full_path = os.path.join(self.storage_base_path, file_path)
        
        try:
            if os.path.exists(full_path):
                os.remove(full_path)
                logger.info(f"Deleted file: {full_path}")
                return True
            else:
                logger.warning(f"File not found for deletion: {full_path}")
                return False
        except Exception as e:
            logger.error(f"Error deleting file: {str(e)}")
            return False