import json
import os
import shutil
from pathlib import Path
from typing import Optional
from pydantic import BaseModel, Field

# ─── Paths ────────────────────────────────────────────────
BASE_DIR = Path(__file__).parent.parent
PROJECTS_FILE = BASE_DIR / "projects.json"
TEMPLATES_DIR = BASE_DIR / "templates"

# ─── Default SVG Icons ────────────────────────────────────
DEFAULT_BAG_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path><line x1="3" y1="6" x2="21" y2="6"></line><path d="M16 10a4 4 0 0 1-8 0"></path></svg>'
DEFAULT_INSTAGRAM_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>'
DEFAULT_GENERIC_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><rect x="7" y="7" width="3" height="9"></rect><rect x="14" y="7" width="3" height="5"></rect></svg>'


# ─── Models ───────────────────────────────────────────────
class ProjectConfig(BaseModel):
    name: str
    prefix: str
    remove_background: bool = True
    product_size_percent: float = Field(default=80.0, ge=0.0, le=110.0)
    canvas_width: int = 1200
    canvas_height: int = 1200
    background_color: str = "#FFFFFF"
    template_file: Optional[str] = None
    description: str = ""
    icon_svg: str = DEFAULT_GENERIC_SVG


class ProjectUpdate(BaseModel):
    name: Optional[str] = None
    prefix: Optional[str] = None
    remove_background: Optional[bool] = None
    product_size_percent: Optional[float] = Field(default=None, ge=0.0, le=110.0)
    canvas_width: Optional[int] = None
    canvas_height: Optional[int] = None
    background_color: Optional[str] = None
    template_file: Optional[str] = None
    description: Optional[str] = None
    icon_svg: Optional[str] = None


# ─── Project Manager ──────────────────────────────────────
class ProjectManager:
    
    def __init__(self):
        self._ensure_files()
    
    def _ensure_files(self):
        TEMPLATES_DIR.mkdir(parents=True, exist_ok=True)
        if not PROJECTS_FILE.exists():
            self._save_projects(self._default_projects())
    
    def _default_projects(self) -> dict:
        return {
            "digikala-white": {
                "name": "Digikala White",
                "prefix": "dk",
                "remove_background": True,
                "product_size_percent": 80.0,
                "canvas_width": 1200,
                "canvas_height": 1200,
                "background_color": "#FFFFFF",
                "template_file": None,
                "description": "دیجیکالا - بکگراند سفید",
                "icon_svg": DEFAULT_BAG_SVG
            },
            "instagram-square": {
                "name": "Instagram Square",
                "prefix": "ig",
                "remove_background": True,
                "product_size_percent": 75.0,
                "canvas_width": 1080,
                "canvas_height": 1080,
                "background_color": "#FFFFFF",
                "template_file": None,
                "description": "اینستاگرام - پست مربعی",
                "icon_svg": DEFAULT_INSTAGRAM_SVG
            }
        }
    
    def _load_projects(self) -> dict:
        with open(PROJECTS_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    
    def _save_projects(self, projects: dict):
        with open(PROJECTS_FILE, "w", encoding="utf-8") as f:
            json.dump(projects, f, ensure_ascii=False, indent=2)
    
    # ─── CRUD ─────────────────────────────────────────────
    def get_all(self) -> dict:
        return self._load_projects()
    
    def get(self, project_id: str) -> Optional[dict]:
        projects = self._load_projects()
        return projects.get(project_id)
    
    def create(self, project_id: str, config: ProjectConfig) -> dict:
        projects = self._load_projects()
        if project_id in projects:
            raise ValueError(f"Project '{project_id}' already exists")
        
        project_dir = TEMPLATES_DIR / project_id
        project_dir.mkdir(parents=True, exist_ok=True)
        
        # استفاده از model_dump به جای dict
        try:
            projects[project_id] = config.model_dump()
        except AttributeError:
            projects[project_id] = config.dict()
            
        self._save_projects(projects)
        return projects[project_id]
    
    def update(self, project_id: str, update: ProjectUpdate) -> dict:
        projects = self._load_projects()
        if project_id not in projects:
            raise ValueError(f"Project '{project_id}' not found")
        
        # تبدیل امن به دیکشنری بر اساس نسخه Pydantic
        try:
            update_data = update.model_dump(exclude_none=True)
        except AttributeError:
            update_data = {k: v for k, v in update.dict().items() if v is not None}
        
        # اعمال تغییرات بر روی پروژه موجود
        projects[project_id].update(update_data)
        self._save_projects(projects)
        return projects[project_id]
    
    def delete(self, project_id: str):
        projects = self._load_projects()
        if project_id not in projects:
            raise ValueError(f"Project '{project_id}' not found")
        
        project_dir = TEMPLATES_DIR / project_id
        if project_dir.exists():
            shutil.rmtree(project_dir)
        
        del projects[project_id]
        self._save_projects(projects)
    
    def set_template(self, project_id: str, filename: str):
        projects = self._load_projects()
        if project_id not in projects:
            raise ValueError(f"Project '{project_id}' not found")
        projects[project_id]["template_file"] = filename
        self._save_projects(projects)
    
    def get_template_path(self, project_id: str) -> Optional[Path]:
        project = self.get(project_id)
        if not project or not project.get("template_file"):
            return None
        path = TEMPLATES_DIR / project_id / project["template_file"]
        return path if path.exists() else None


# Singleton
project_manager = ProjectManager()
