# 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():
    """
    POST /posts
    接收 application/json 格式：
        { "user_id": ..., "title": ..., "content": ..., "topic_id": ..., "media_urls": [...], "status": ... }
    """
    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=xx  → 返回指定用户的所有帖子
    """
    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,
        '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):
    """
    GET /posts/<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):
    """
    PUT /posts/<post_id>
    接收 application/json 格式，可选字段：
        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):
    """
    DELETE /posts/<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>/like', methods=['GET'])
def has_liked(post_id):
    """
    GET /posts/<post_id>/like?user_id=xx
    返回 { "liked": true/false }
    """
    user_id = request.args.get('user_id', type=int)
    if not user_id:
        abort(400, 'user_id required')

    exists = Behavior.query.filter_by(
        user_id=user_id,
        post_id=post_id,
        type='like'
    ).first() is not None

    return jsonify({'liked': exists}), 200


@posts_bp.route('/<int:post_id>/like', methods=['DELETE'])
def unlike(post_id):
    """
    DELETE /posts/<post_id>/like
    body: { "user_id": xx }
    """
    data    = request.get_json(silent=True) or {}
    user_id = data.get('user_id')
    if not user_id:
        abort(400, 'user_id required')

    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):
    """
    DELETE /posts/<post_id>/favorite
    body: { "user_id": xx }
    """
    data    = request.get_json(silent=True) or {}
    user_id = data.get('user_id')
    if not user_id:
        abort(400, 'user_id required')

    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


@posts_bp.route('/<int:post_id>/<action>', methods=['POST'])
def post_action(post_id, action):
    """
    POST /posts/<post_id>/<action>
    支持 action: like, favorite, view, share
    """
    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')

    # 幂等检查
    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
