# src/character_preview.py
import pygame
import os
from client.data import config
from client.resource_path import get_asset_path, get_resource_path

class CharacterPreview:
    def __init__(self, font, screen_width, screen_height, scale=4):
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.scale = scale
        self._cache = {}  # cache loaded frame surfaces by path
        
        self.font = pygame.font.SysFont(config.FONT_NAME, max(20, int(config.SCREEN_HEIGHT * 0.04))) # Font size proportional to screen height

    def draw_preview(self, screen, appearance=None, gear=None, pos=None):
        if not appearance:
            appearance = {}
        if not gear:
            gear = {}

        gender = appearance.get("gender", "Male")
        hair = appearance.get("hair")
        direction = appearance.get("direction", "front")

        # Map direction to row index in Idle.png
        direction_rows = {
            "back": 0,
            "left": 1,
            "front": 2,
            "right": 3
        }
        row_idx = direction_rows.get(direction, 2)

        cx, cy = (self.screen_width // 2, self.screen_height // 1.3) if pos is None else pos

        def try_blit(path):
            if not path:
                return
            frame = self._load_frame(path, row_idx=row_idx)  # use direction row
            if frame:
                x = cx - frame.get_width() // 2
                y = cy - frame.get_height() // 2
                screen.blit(frame, (x, y))

        # Draw layers in proper order

        # 1. Body
        body_path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Body", gender, "Idle.png"))
        try_blit(body_path)

        # 2. Clothing layers
        clothing_layers = {
            "Feet": gear.get("feet", "Shoes 01 - Shoes"),
            "Legs": gear.get("pants", "Pants 03 - Pants"),
            "Torso": gear.get("armor", "Shirt 04 - T-shirt")
        }
        for layer, name in clothing_layers.items():
            path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Clothing", gender, layer, name, "Idle.png"))
            try_blit(path)

        # 3. Head
        head_path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Head", gender, "Idle.png"))
        try_blit(head_path)

        # 4. Helm/Accessory
        for layer, key in [("Helm", "helm"), ("Accessory", "accessory")]:
            item = gear.get(key)
            if item:
                path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Equipment", layer, item, "Idle.png"))
                try_blit(path)

        # 5. Hair
        if hair:
            hair_path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Hair", hair, "Idle.png"))
            try_blit(hair_path)

        # 6. Weapon
        weapon = gear.get("weapon")
        if weapon:
            path = get_resource_path(os.path.join("client", "assets", "images", "Characters", "Equipment", "Weapon", weapon, "Idle.png"))
            try_blit(path)

    def _load_frame(self, path, cols=3, rows=4, row_idx=2, col_idx=0):
        if not path:
            return None
        key = (path, cols, rows, row_idx, col_idx, self.scale)
        if key in self._cache:
            return self._cache[key]

        try:
            sheet = pygame.image.load(path).convert_alpha()
        except (pygame.error, FileNotFoundError) as e:
            print(f"[CharacterPreview] Failed to load: {path} - {e}")
            return None
            
        fw = sheet.get_width() // cols
        fh = sheet.get_height() // rows
        rect = pygame.Rect(col_idx*fw, row_idx*fh, fw, fh)
        try:
            frame = sheet.subsurface(rect).copy()
        except Exception:
            frame = sheet.copy()

        scaled = pygame.transform.smoothscale(frame, (fw*self.scale, fh*self.scale))
        self._cache[key] = scaled
        return scaled

def _find_case_variants(path):
    if os.path.exists(path):
        return path
    dirname, fname = os.path.split(path)
    candidates = [fname, fname.lower(), fname.capitalize()]
    for c in candidates:
        p = os.path.join(dirname, c)
        if os.path.exists(p):
            return p
    return None
