# routes/posts.py

from flask import Blueprint, request, jsonify, abort
from extensions    import db
from models.post   import Post
from models.behavior import Behavior

posts_bp = Blueprint('posts', __name__)

@posts_bp.route('', methods=['POST'])
def create_post():
    data = request.get_json() or {}
    post = Post(**data)
    db.session.add(post)
    db.session.commit()
    return jsonify({'id': post.id}), 201

@posts_bp.route('', methods=['GET'])
def list_posts():
    """
    获取帖子列表，支持：
      - GET /posts              返回所有已发布帖子
      - GET /posts?user_id=123  返回指定用户 user_id 的所有帖子
    """
    user_id = request.args.get('user_id', type=int)
    query = Post.query
    if user_id is not None:
        query = query.filter_by(user_id=user_id)
    else:
        query = query.filter_by(status='published')
    posts = query.all()

    return jsonify([{
        'id': p.id,
        'title': p.title,
        'heat': p.heat,
        'status': p.status,
        'created_at': p.created_at.isoformat()
    } for p in posts])

@posts_bp.route('/<int:post_id>', methods=['GET'])
def get_post(post_id):
    post = Post.query.get_or_404(post_id)
    return jsonify({
        'id': post.id,
        'user_id': post.user_id,
        'topic_id': post.topic_id,
        'title': post.title,
        'content': post.content,
        'media_urls': post.media_urls,
        'status': post.status,
        'heat': post.heat,
        'created_at': post.created_at.isoformat(),
        'updated_at': post.updated_at.isoformat()
    })

@posts_bp.route('/<int:post_id>', methods=['PUT'])
def update_post(post_id):
    """
    修改帖子字段（可选字段：title, content, topic_id, media_urls, status）
    """
    post = Post.query.get_or_404(post_id)
    data = request.get_json() or {}
    for key in ('title', 'content', 'topic_id', 'media_urls', 'status'):
        if key in data:
            setattr(post, key, data[key])
    db.session.commit()
    return '', 204

@posts_bp.route('/<int:post_id>', methods=['DELETE'])
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    db.session.delete(post)
    db.session.commit()
    return '', 204

@posts_bp.route('/<int:post_id>/<action>', methods=['POST'])
def post_action(post_id, action):
    """
    支持的 action: like, favorite, view, share
    对于 like 和 favorite，保证每个用户每帖只做一次。
    """
    if action not in ('like', 'favorite', 'view', 'share'):
        abort(400, 'Invalid action')

    data = request.get_json() or {}
    user_id = data.get('user_id')
    if not user_id:
        abort(400, 'user_id required')

    # 对 like/favorite 做去重检查
    if action in ('like', 'favorite'):
        exists = Behavior.query.filter_by(
            user_id=user_id,
            post_id=post_id,
            type=action
        ).first()
        if exists:
            return jsonify({'error': f'already {action}d'}), 400

    # 创建行为记录
    beh = Behavior(user_id=user_id, post_id=post_id, type=action)
    db.session.add(beh)

    # 更新热度
    post = Post.query.get_or_404(post_id)
    post.heat += 1

    db.session.commit()
    return '', 201

@posts_bp.route('/<int:post_id>/like', methods=['DELETE'])
def unlike(post_id):
    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
    if not user_id:
        abort(400, 'user_id required')
    # 查找已有的 like 行为
    beh = Behavior.query.filter_by(
        user_id=user_id,
        post_id=post_id,
        type='like'
    ).first()
    if not beh:
        return jsonify({'error': 'not liked yet'}), 400

    db.session.delete(beh)
    # 更新热度，确保不降到负数
    post = Post.query.get_or_404(post_id)
    post.heat = max(post.heat - 1, 0)
    db.session.commit()
    return '', 204

@posts_bp.route('/<int:post_id>/favorite', methods=['DELETE'])
def unfavorite(post_id):
    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
    if not user_id:
        abort(400, 'user_id required')
    # 查找已有的 favorite 行为
    beh = Behavior.query.filter_by(
        user_id=user_id,
        post_id=post_id,
        type='favorite'
    ).first()
    if not beh:
        return jsonify({'error': 'not favorited yet'}), 400

    db.session.delete(beh)
    # 更新热度
    post = Post.query.get_or_404(post_id)
    post.heat = max(post.heat - 1, 0)
    db.session.commit()
    return '', 204