# 标签蓝图
# 处理标签的增删改查以及录音与标签的关联管理

from flask import Blueprint, request, jsonify
from flask_login import login_required, current_user
from datetime import datetime

from src.clients import db
from src.models import Tag, RecordingTag, Recording

# 创建标签蓝图
tag_bp = Blueprint('tag', __name__)

# 全局对象（从 app.py 导入）
limiter = None
csrf = None

def init_tag_bp(limiter_instance, csrf_instance):
    """初始化蓝图所需的全局对象"""
    global limiter, csrf
    limiter = limiter_instance
    csrf = csrf_instance


@tag_bp.route('/api/tags', methods=['GET'])
@login_required
def get_tags():
    """获取当前用户的所有标签，包括全局标签和私有标签"""
    try:
        # 先查询全局标签（visibility='global'）
        global_tags = Tag.query.filter_by(visibility='global').order_by(Tag.name).all()

        # 再查询当前用户的私有标签（visibility='private' 且 user_id=current_user.id）
        private_tags = Tag.query.filter_by(
            user_id=current_user.id,
            visibility='private'
        ).order_by(Tag.name).all()

        # 合并结果
        all_tags = global_tags + private_tags

        return jsonify([tag.to_dict() for tag in all_tags])
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@tag_bp.route('/api/tags', methods=['POST'])
@login_required
def create_tag():
    """创建新标签"""
    data = request.get_json()

    if not data or not data.get('name'):
        return jsonify({'error': '标签名称是必需的'}), 400

    visibility = data.get('visibility', 'private')

    # 检查是否尝试创建全局标签
    if visibility == 'global':
        # 只有管理员可以创建全局标签
        if not current_user.is_admin:
            return jsonify({'error': '只有管理员可以创建全局标签'}), 403

        # 检查全局标签名称是否已存在（全局标签名称必须唯一）
        existing_global_tag = Tag.query.filter_by(
            name=data['name'],
            visibility='global'
        ).first()
        if existing_global_tag:
            return jsonify({'error': '全局标签名称已存在'}), 400
    else:
        # 私有标签：检查同一用户下是否已存在相同名称的私有标签
        existing_private_tag = Tag.query.filter_by(
            name=data['name'],
            user_id=current_user.id,
            visibility='private'
        ).first()
        if existing_private_tag:
            return jsonify({'error': '您已存在同名的私有标签'}), 400

    tag = Tag(
        name=data['name'],
        user_id=current_user.id,
        visibility=visibility,
        color=data.get('color', '#3B82F6'),
        custom_prompt=data.get('custom_prompt'),
        default_language=data.get('default_language'),
        default_min_speakers=data.get('default_min_speakers'),
        default_max_speakers=data.get('default_max_speakers')
    )

    db.session.add(tag)
    db.session.commit()

    return jsonify(tag.to_dict()), 201


@tag_bp.route('/api/tags/<int:tag_id>', methods=['PUT'])
@login_required
def update_tag(tag_id):
    """更新标签"""
    tag = Tag.query.filter_by(id=tag_id).first_or_404()
    data = request.get_json()

    # 权限检查
    if tag.visibility == 'global':
        # 只有管理员可以修改全局标签
        if not current_user.is_admin:
            return jsonify({'error': '只有管理员可以修改全局标签'}), 403
    else:
        # 私有标签：只有标签所有者可以修改
        if tag.user_id != current_user.id:
            return jsonify({'error': '您没有权限修改此标签'}), 403

    if 'name' in data:
        # 检查新名称是否冲突
        if tag.visibility == 'global':
            # 全局标签名称必须全局唯一
            existing_tag = Tag.query.filter_by(
                name=data['name'],
                visibility='global'
            ).filter(Tag.id != tag_id).first()
            if existing_tag:
                return jsonify({'error': '全局标签名称已存在'}), 400
        else:
            # 私有标签名称在用户内必须唯一
            existing_tag = Tag.query.filter_by(
                name=data['name'],
                user_id=current_user.id,
                visibility='private'
            ).filter(Tag.id != tag_id).first()
            if existing_tag:
                return jsonify({'error': '您已存在同名的私有标签'}), 400
        tag.name = data['name']

    if 'visibility' in data:
        new_visibility = data['visibility']
        if new_visibility != tag.visibility:
            # 只有管理员可以修改标签的可见性
            if not current_user.is_admin:
                return jsonify({'error': '只有管理员可以修改标签可见性'}), 403

            if new_visibility == 'global':
                # 检查全局标签名称是否已存在
                existing_global_tag = Tag.query.filter_by(
                    name=tag.name,
                    visibility='global'
                ).first()
                if existing_global_tag:
                    return jsonify({'error': '全局标签名称已存在'}), 400
            else:
                # 全局改个人：检查个人标签名称是否冲突
                # 注意：这里使用 current_user.id 作为目标用户ID
                existing_private_tag = Tag.query.filter_by(
                    name=tag.name,
                    user_id=current_user.id,
                    visibility='private'
                ).first()
                if existing_private_tag:
                    return jsonify({'error': '您已存在同名的私有标签'}), 400

            tag.visibility = new_visibility

    if 'color' in data:
        tag.color = data['color']
    if 'custom_prompt' in data:
        tag.custom_prompt = data['custom_prompt']
    if 'default_language' in data:
        tag.default_language = data['default_language']
    if 'default_min_speakers' in data:
        tag.default_min_speakers = data['default_min_speakers']
    if 'default_max_speakers' in data:
        tag.default_max_speakers = data['default_max_speakers']

    tag.updated_at = datetime.utcnow()
    db.session.commit()

    return jsonify(tag.to_dict())


@tag_bp.route('/api/tags/<int:tag_id>', methods=['DELETE'])
@login_required
def delete_tag(tag_id):
    """删除标签"""
    tag = Tag.query.filter_by(id=tag_id).first_or_404()

    # 权限检查
    if tag.visibility == 'global':
        # 只有管理员可以删除全局标签
        if not current_user.is_admin:
            return jsonify({'error': '只有管理员可以删除全局标签'}), 403
    else:
        # 私有标签：只有标签所有者可以删除
        if tag.user_id != current_user.id:
            return jsonify({'error': '您没有权限删除此标签'}), 403

    db.session.delete(tag)
    db.session.commit()
    return jsonify({'success': True})


@tag_bp.route('/api/recordings/<int:recording_id>/tags', methods=['POST'])
@login_required
def add_tag_to_recording(recording_id):
    """为录音添加标签"""
    recording = Recording.query.filter_by(id=recording_id, user_id=current_user.id).first_or_404()
    data = request.get_json()

    tag_id = data.get('tag_id')
    if not tag_id:
        return jsonify({'error': 'tag_id 是必需的'}), 400

    tag = Tag.query.filter_by(id=tag_id, user_id=current_user.id).first_or_404()

    # 检查标签是否已与录音关联
    existing_association = RecordingTag.query.filter_by(recording_id=recording_id, tag_id=tag_id).first()
    if not existing_association:
        # 获取当前录音的最大排序号
        max_order = db.session.query(db.func.max(RecordingTag.order)).filter_by(recording_id=recording_id).scalar() or 0

        # 创建新关联，设置正确的排序号
        new_association = RecordingTag(
            recording_id=recording_id,
            tag_id=tag_id,
            order=max_order + 1,
            added_at=datetime.utcnow()
        )
        db.session.add(new_association)
        db.session.commit()

    return jsonify({'success': True, 'tags': [t.to_dict() for t in recording.tags]})


@tag_bp.route('/api/recordings/<int:recording_id>/tags/<int:tag_id>', methods=['DELETE'])
@login_required
def remove_tag_from_recording(recording_id, tag_id):
    """从录音中移除标签"""
    recording = Recording.query.filter_by(id=recording_id, user_id=current_user.id).first_or_404()
    tag = Tag.query.filter_by(id=tag_id, user_id=current_user.id).first_or_404()

    # 查找并删除关联
    association = RecordingTag.query.filter_by(recording_id=recording_id, tag_id=tag_id).first()
    if association:
        db.session.delete(association)
        db.session.commit()

    return jsonify({'success': True, 'tags': [t.to_dict() for t in recording.tags]})
