# routes/posts.py

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

posts_bp = Blueprint('posts', __name__)

@posts_bp.route('', methods=['POST'])
def create_post():
    try:
        user_id     = request.form.get('user_id')
        title       = request.form.get('title')
        content     = request.form.get('content')
        status      = request.form.get('status', 'published')
        topic_id    = request.form.get('topic_id')
        media_count = int(request.form.get('media_count', 0))

        if not user_id or not title or not content:
            return jsonify({'error': '缺少必要字段'}), 400

        files = []
        for i in range(media_count):
            key = f'media_{i}'
            if key in request.files:
                files.append(request.files[key])

        fpost = Fpost(db.session)
        new_post = fpost.create_post_with_files(
            user_id=int(user_id),
            title=title,
            content=content,
            topic_id=int(topic_id) if topic_id else None,
            status=status,
            files=files
        )

        return jsonify({'id': new_post.id}), 201

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@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):
    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):
    """
    支持 FormData 和 JSON 两种格式更新：
      - multipart/form-data 时可上传新文件并保留 existing_media_urls
      - application/json 时只修改字段
    """
    try:
        fpost = Fpost(db.session)

        if request.content_type and 'multipart/form-data' in request.content_type:
            title    = request.form.get('title')
            content  = request.form.get('content')
            status   = request.form.get('status')
            topic_id = request.form.get('topic_id')
            count    = int(request.form.get('media_count', 0))
            existing = request.form.get('existing_media_urls')

            existing_media_urls = None
            if existing:
                try:
                    existing_media_urls = json.loads(existing)
                except:
                    existing_media_urls = None

            files = []
            for i in range(count):
                key = f'media_{i}'
                if key in request.files:
                    files.append(request.files[key])

            updated = fpost.update_post_with_files(
                post_id=post_id,
                title=title,
                content=content,
                topic_id=int(topic_id) if topic_id else None,
                status=status,
                files=files or None,
                existing_media_urls=existing_media_urls
            )
        else:
            post = Post.query.get_or_404(post_id)
            data = request.get_json() or {}
            for field in ('title','content','topic_id','media_urls','status'):
                if field in data:
                    setattr(post, field, data[field])
            db.session.commit()
            updated = post

        if not updated:
            return jsonify({'error': '帖子不存在'}), 404

        return '', 204

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@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


# —— 显式的 like/favorite 删除和查询路由，放在泛用 action 路由之前 —— #

@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):
    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):
    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


# —— 泛用 action 路由，仅处理 POST /posts/<id>/(like|favorite|view|share) —— #

@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')

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