#!/usr/bin/env python3
"""
媒体存储管理
"""

import json
import os
from pathlib import Path
from typing import List, Optional
from dataclasses import asdict

from .types import VideoSegment, OriginalVideo
from python_core.config import settings
from python_core.utils.logger import logger

class MediaStorage:
    """媒体存储管理器"""

    def __init__(self):
        self.cache_dir = settings.temp_dir / "cache"
        self.cache_dir.mkdir(parents=True, exist_ok=True)

        # 数据文件
        self.segments_file = self.cache_dir / "video_segments.json"
        self.original_videos_file = self.cache_dir / "original_videos.json"

        # 存储目录
        self.video_storage_dir = settings.temp_dir / "video_storage"
        self.video_storage_dir.mkdir(parents=True, exist_ok=True)

        self.segments_dir = settings.temp_dir / "video_segments"
        self.segments_dir.mkdir(parents=True, exist_ok=True)

        self.thumbnails_dir = settings.temp_dir / "video_thumbnails"
        self.thumbnails_dir.mkdir(parents=True, exist_ok=True)

    def load_video_segments(self) -> List[VideoSegment]:
        """加载视频片段数据"""
        if self.segments_file.exists():
            try:
                with open(self.segments_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return [VideoSegment(**item) for item in data]
            except Exception as e:
                logger.error(f"Failed to load video segments: {e}")
                return []
        return []

    def load_original_videos(self) -> List[OriginalVideo]:
        """加载原始视频数据"""
        if self.original_videos_file.exists():
            try:
                with open(self.original_videos_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return [OriginalVideo(**item) for item in data]
            except Exception as e:
                logger.error(f"Failed to load original videos: {e}")
                return []
        return []

    def save_video_segments(self, segments: List[VideoSegment]):
        """保存视频片段数据"""
        try:
            data = [asdict(segment) for segment in segments]
            with open(self.segments_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            logger.info(f"Video segments saved to {self.segments_file}")
        except Exception as e:
            logger.error(f"Failed to save video segments: {e}")
            raise

    def save_original_videos(self, videos: List[OriginalVideo]):
        """保存原始视频数据"""
        try:
            data = [asdict(video) for video in videos]
            with open(self.original_videos_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            logger.info(f"Original videos saved to {self.original_videos_file}")
        except Exception as e:
            logger.error(f"Failed to save original videos: {e}")
            raise

    def get_video_by_md5(self, videos: List[OriginalVideo], md5_hash: str) -> Optional[OriginalVideo]:
        """根据MD5获取原始视频"""
        for video in videos:
            if video.md5_hash == md5_hash and video.is_active:
                return video
        return None

    def get_segment_by_md5(self, segments: List[VideoSegment], md5_hash: str) -> Optional[VideoSegment]:
        """根据MD5获取视频片段"""
        for segment in segments:
            if segment.md5_hash == md5_hash and segment.is_active:
                return segment
        return None

    def get_segments_by_video_id(self, segments: List[VideoSegment], video_id: str) -> List[VideoSegment]:
        """获取指定原始视频的所有片段"""
        result = []
        for segment in segments:
            if segment.original_video_id == video_id and segment.is_active:
                result.append(segment)
        return sorted(result, key=lambda x: x.segment_index)

    def get_segments_by_tags(self, segments: List[VideoSegment], tags: List[str], match_all: bool = False) -> List[VideoSegment]:
        """根据标签搜索视频片段"""
        results = []
        tag_set = set(tags)

        for segment in segments:
            if not segment.is_active:
                continue

            segment_tags = set(segment.tags)

            if match_all:
                # 必须包含所有标签
                if tag_set.issubset(segment_tags):
                    results.append(segment)
            else:
                # 包含任意一个标签
                if tag_set.intersection(segment_tags):
                    results.append(segment)

        return results

    def search_segments(self, segments: List[VideoSegment], keyword: str) -> List[VideoSegment]:
        """搜索视频片段"""
        keyword = keyword.lower()
        results = []

        for segment in segments:
            if not segment.is_active:
                continue

            # 搜索文件名和标签
            if (keyword in segment.filename.lower() or
                any(keyword in tag.lower() for tag in segment.tags)):
                results.append(segment)

        return results

    def get_popular_segments(self, segments: List[VideoSegment], limit: int = 10) -> List[VideoSegment]:
        """获取最常用的视频片段"""
        active_segments = [segment for segment in segments if segment.is_active]
        sorted_segments = sorted(active_segments, key=lambda x: x.use_count, reverse=True)
        return sorted_segments[:limit]

    def delete_segment_files(self, segment: VideoSegment) -> bool:
        """删除片段的物理文件"""
        try:
            if os.path.exists(segment.file_path):
                os.remove(segment.file_path)

            # 删除缩略图
            if segment.thumbnail_path and os.path.exists(segment.thumbnail_path):
                os.remove(segment.thumbnail_path)

            logger.info(f"Deleted segment files: {segment.filename}")
            return True
        except Exception as e:
            logger.error(f"Failed to delete segment files: {e}")
            return False

    def delete_video_files(self, video: OriginalVideo) -> bool:
        """删除视频的物理文件"""
        try:
            if os.path.exists(video.file_path):
                os.remove(video.file_path)

            logger.info(f"Deleted video file: {video.filename}")
            return True
        except Exception as e:
            logger.error(f"Failed to delete video file: {e}")
            return False
