# 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,
        'status': p.status,                     # 新增 status 字段
        'heat': p.heat,
        '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