# 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):
            file_key = f'media_{i}'
            if file_key in request.files:
                files.append(request.files[file_key])
        
        # 使用 Fpost 创建帖子
        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=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）
    支持FormData和JSON两种格式
    """
    try:
        fpost = Fpost(db.session)
        
        # 检查是否是FormData请求
        if request.content_type and 'multipart/form-data' in request.content_type:
            # FormData请求
            title = request.form.get('title')
            content = request.form.get('content')
            status = request.form.get('status')
            topic_id = request.form.get('topic_id')
            media_count = int(request.form.get('media_count', 0))
            existing_media_urls_str = request.form.get('existing_media_urls')
            
            # 解析现有媒体URLs
            existing_media_urls = None
            if existing_media_urls_str:
                try:
                    existing_media_urls = json.loads(existing_media_urls_str)
                except:
                    existing_media_urls = None
            
            # 获取新上传的文件
            files = []
            for i in range(media_count):
                file_key = f'media_{i}'
                if file_key in request.files:
                    files.append(request.files[file_key])
            
            # 更新帖子
            updated_post = 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 if files else None,
                existing_media_urls=existing_media_urls
            )
            
        else:
            # JSON请求（保持原有逻辑）
            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()
            updated_post = post
        
        if not updated_post:
            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

@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