from flask import Blueprint, request, jsonify
from tinydb import Query

from api.utils import send_event_for_current_user
from db.db import reward_db, child_db
from events.types.event import Event
from events.types.event_types import EventType
from events.types.reward_modified import RewardModified
from models.reward import Reward

reward_api = Blueprint('reward_api', __name__)

# Reward endpoints
@reward_api.route('/reward/add', methods=['PUT'])
def add_reward():
    data = request.get_json()
    name = data.get('name')
    description = data.get('description')
    cost = data.get('cost')
    image = data.get('image_id', '')
    if not name or description is None or cost is None:
        return jsonify({'error': 'Name, description, and cost are required'}), 400
    reward = Reward(name=name, description=description, cost=cost, image_id=image)
    reward_db.insert(reward.to_dict())
    resp = send_event_for_current_user(Event(EventType.REWARD_MODIFIED.value,
                                        RewardModified(reward.id, RewardModified.OPERATION_ADD)))
    if resp:
        return resp
    return jsonify({'message': f'Reward {name} added.'}), 201



@reward_api.route('/reward/<id>', methods=['GET'])
def get_reward(id):
    RewardQuery = Query()
    result = reward_db.search(RewardQuery.id == id)
    if not result:
        return jsonify({'error': 'Reward not found'}), 404
    return jsonify(result[0]), 200

@reward_api.route('/reward/list', methods=['GET'])
def list_rewards():
    rewards = reward_db.all()
    return jsonify({'rewards': rewards}), 200

@reward_api.route('/reward/<id>', methods=['DELETE'])
def delete_reward(id):
    RewardQuery = Query()
    removed = reward_db.remove(RewardQuery.id == id)
    if removed:
        # remove the reward id from any child's reward list
        ChildQuery = Query()
        for child in child_db.all():
            rewards = child.get('rewards', [])
            if id in rewards:
                rewards.remove(id)
                child_db.update({'rewards': rewards}, ChildQuery.id == child.get('id'))
                resp = send_event_for_current_user(Event(EventType.REWARD_MODIFIED.value,
                                                    RewardModified(id, RewardModified.OPERATION_DELETE)))
                if resp:
                    return resp
        return jsonify({'message': f'Reward {id} deleted.'}), 200
    return jsonify({'error': 'Reward not found'}), 404

@reward_api.route('/reward/<id>/edit', methods=['PUT'])
def edit_reward(id):
    RewardQuery = Query()
    existing = reward_db.get(RewardQuery.id == id)
    if not existing:
        return jsonify({'error': 'Reward not found'}), 404

    data = request.get_json(force=True) or {}
    updates = {}

    if 'name' in data:
        name = (data.get('name') or '').strip()
        if not name:
            return jsonify({'error': 'Name cannot be empty'}), 400
        updates['name'] = name

    if 'description' in data:
        desc = (data.get('description') or '').strip()
        if not desc:
            return jsonify({'error': 'Description cannot be empty'}), 400
        updates['description'] = desc

    if 'cost' in data:
        cost = data.get('cost')
        if not isinstance(cost, int):
            return jsonify({'error': 'Cost must be an integer'}), 400
        if cost <= 0:
            return jsonify({'error': 'Cost must be a positive integer'}), 400
        updates['cost'] = cost

    if 'image_id' in data:
        updates['image_id'] = data.get('image_id', '')

    if not updates:
        return jsonify({'error': 'No valid fields to update'}), 400

    reward_db.update(updates, RewardQuery.id == id)
    updated = reward_db.get(RewardQuery.id == id)
    resp = send_event_for_current_user(Event(EventType.REWARD_MODIFIED.value,
                                        RewardModified(id, RewardModified.OPERATION_EDIT)))
    if resp:
        return resp

    return jsonify(updated), 200
