from flask import request
from flask_restx import Resource, Namespace, fields
from app.service.user_room_service import UserRoomService
from app.utils.jwt_utils import token_required
from app.utils.logger import Logger, log_request_info
from app import db


api = Namespace('user_room', description='用户账号与房间ID映射管理')


user_room_model = api.model('UserRoom', {
    'id': fields.Integer(readOnly=True, description='记录ID'),
    'user_account': fields.String(required=True, description='用户账号'),
    'room_id': fields.String(required=True, description='房间ID')
})


user_room_input_model = api.model('UserRoomInput', {
    'user_account': fields.String(required=True, description='用户账号'),
    'room_id': fields.String(required=True, description='房间ID')
})


@api.route('/')
class UserRoomListResource(Resource):
    @token_required
    @api.marshal_list_with(user_room_model)
    @log_request_info
    def get(self):
        """获取所有映射"""
        Logger.info("获取用户房间映射列表")
        service = UserRoomService(db.session)
        records = service.list_all()
        
        Logger.info("用户房间映射列表获取成功", {
            'record_count': len(records)
        })
        
        return [r.to_dict() for r in records]

    @token_required
    @api.expect(user_room_input_model, validate=True)
    @api.marshal_with(user_room_model, code=201)
    @log_request_info
    def post(self):
        """创建新映射"""
        data = request.get_json()
        service = UserRoomService(db.session)
        
        Logger.info("创建用户房间映射", {
            'user_account': data.get('user_account'),
            'room_id': data.get('room_id')
        })
        
        try:
            new_record = service.create(user_account=data['user_account'], room_id=data['room_id'])
            
            Logger.info("用户房间映射创建成功", {
                'record_id': new_record.id,
                'user_account': new_record.user_account,
                'room_id': new_record.room_id
            })
            
            return new_record.to_dict(), 201
        except ValueError as e:
            Logger.warning("用户房间映射创建失败", {
                'user_account': data.get('user_account'),
                'room_id': data.get('room_id'),
                'error': str(e)
            })
            api.abort(400, str(e))


@api.route('/<int:record_id>')
class UserRoomResource(Resource):
    @token_required
    @api.marshal_with(user_room_model)
    @api.response(404, 'Record not found')
    def get(self, record_id: int):
        """根据ID获取映射"""
        service = UserRoomService(db.session)
        try:
            record = service.get_by_id(record_id)
            return record.to_dict()
        except ValueError as e:
            api.abort(404, str(e))

    @token_required
    @api.expect(api.model('UserRoomUpdate', {
        'user_account': fields.String(description='用户账号'),
        'room_id': fields.String(description='房间ID')
    }))
    @api.marshal_with(user_room_model)
    @api.response(404, 'Record not found')
    def put(self, record_id: int):
        """更新映射"""
        data = request.get_json()
        service = UserRoomService(db.session)
        try:
            updated = service.update(
                record_id=record_id,
                user_account=data.get('user_account'),
                room_id=data.get('room_id')
            )
            return updated.to_dict()
        except ValueError as e:
            # 可能是未找到或唯一冲突等
            api.abort(400 if 'exists' in str(e) else 404, str(e))

    @token_required
    @api.response(204, 'Record deleted')
    @api.response(404, 'Record not found')
    def delete(self, record_id: int):
        """删除映射"""
        service = UserRoomService(db.session)
        try:
            service.delete(record_id)
            return '', 204
        except ValueError as e:
            api.abort(404, str(e))

@api.route('/by-user/<string:user_account>')
class UserRoomByUserResource(Resource):
    @token_required
    @api.marshal_list_with(api.model('UserRoomDetails', {
        'id': fields.Integer(description='记录ID'),
        'user_account': fields.String(description='用户账号'),
        'room_name': fields.String(description='房间名称'),
        'room_url': fields.String(description='房间URL'),
        'room_id': fields.String(description='房间ID')
    }))
    def get(self, user_account: str):
        """根据用户账号返回房间映射详情列表（用户账号、房间名、房间URL）"""
        service = UserRoomService(db.session)
        results = service.list_details_by_user_account(user_account)
        return results


