import os
import json
from datetime import datetime

import xbmcaddon
import xbmcgui
import xbmcvfs
from xbmcvfs import exists, mkdirs, translatePath


class FavoritesManager:
    def __init__(self):
        self.addon = xbmcaddon.Addon()
        self.profile_path = xbmcvfs.translatePath(self.addon.getAddonInfo('profile'))
        self.favorites_path = os.path.join(self.profile_path, 'favorites.json')
        if not xbmcvfs.exists(self.profile_path):
            xbmcvfs.mkdirs(self.profile_path)
        if not xbmcvfs.exists(self.favorites_path):
            self.save_favorites([])

    def load_favorites(self):
        try:
            with open(self.favorites_path, 'r') as f:
                return json.load(f)
        except Exception:
            return []

    def save_favorites(self, favorites):
        try:
            with open(self.favorites_path, 'w') as f:
                json.dump(favorites, f, indent=2)
        except Exception:
            pass

    def is_favorite(self, channel_id):
        favorites = self.load_favorites()
        return any(f['tvg_id'] == channel_id for f in favorites)

    def add_favorite(self, channel):
        favorites = self.load_favorites()
        if not any(f['tvg_id'] == channel['tvg_id'] for f in favorites):
            favorites.append(channel)
            self.save_favorites(favorites)
            return True
        return False

    def remove_favorite(self, channel_id):
        favorites = self.load_favorites()
        favorites = [f for f in favorites if f['tvg_id'] != channel_id]
        self.save_favorites(favorites)


class LastWatchedManager:
    def __init__(self):
        self.addon = xbmcaddon.Addon()
        self.profile_path = translatePath(self.addon.getAddonInfo('profile'))
        try:
            os.makedirs(self.profile_path, exist_ok=True)
        except PermissionError:
            self.profile_path = xbmcvfs.translatePath("special://temp/")
            os.makedirs(self.profile_path, exist_ok=True)
        except Exception as e:
            raise RuntimeError(f"Cannot create directory: {str(e)}")
        self.last_watched_path = os.path.join(self.profile_path, 'last_watched.json')
        try:
            self.max_channels = int(self.addon.getSetting('max_last_watched') or '10')
        except Exception:
            self.max_channels = 10
        if not os.path.exists(self.last_watched_path):
            self.save_last_watched([])

    def load_last_watched(self):
        try:
            if not exists(self.last_watched_path):
                self.save_last_watched([])
                return []
            with open(self.last_watched_path, 'r', encoding='utf-8') as f:
                content = f.read()
                if not content.strip():
                    return []
                data = json.loads(content)
                if not isinstance(data, list):
                    self.save_last_watched([])
                    return []
                return data
        except Exception:
            return []

    def save_last_watched(self, channels):
        temp_path = self.last_watched_path + '.tmp'
        try:
            directory = os.path.dirname(self.last_watched_path)
            if not exists(directory):
                mkdirs(directory)
            if not os.access(directory, os.W_OK):
                raise PermissionError(f"No write permission for {directory}")
            json_data = json.dumps(channels, indent=2, ensure_ascii=False)
            with open(temp_path, 'w', encoding='utf-8') as f:
                f.write(json_data)
            if exists(self.last_watched_path):
                os.remove(self.last_watched_path)
            os.rename(temp_path, self.last_watched_path)
        except Exception as e:
            if exists(temp_path):
                try:
                    os.remove(temp_path)
                except Exception:
                    pass
            raise IOError(f"Failed to save last watched file: {str(e)}")

    def add_last_watched(self, channel):
        try:
            required_fields = ['name', 'tvg_id', 'url']
            missing_fields = [field for field in required_fields if field not in channel or not channel[field]]
            if missing_fields:
                raise ValueError(f"Missing or empty fields: {missing_fields}")
            channels = self.load_last_watched()
            channels = [c for c in channels if c['tvg_id'] != channel['tvg_id']]
            channel_data = {
                'name': channel['name'],
                'tvg_id': channel['tvg_id'],
                'url': channel['url'],
                'logo': channel.get('logo', ''),
                'group': channel.get('group', ''),
                'added': datetime.now().isoformat()
            }
            channels.insert(0, channel_data)
            channels = channels[:self.max_channels]
            self.save_last_watched(channels)
            saved_channels = self.load_last_watched()
            if not saved_channels and channels:
                raise Exception("Failed to verify save channels")
        except Exception as e:
            raise IOError(f"Failed to add channel: {str(e)}")

    def clear_history(self):
        self.save_last_watched([])
        xbmcgui.Dialog().notification('TV Guide', 'Last watched history cleared')
