"""Tier Admin API — manage features, pricing, payments (admin only)."""
import os
from datetime import datetime
from flask import Blueprint, jsonify, request, current_app
from werkzeug.utils import secure_filename
from app.helpers.auth import admin_required
from flask_login import current_user

api_tier_admin_bp = Blueprint('api_tier_admin', __name__,
                               url_prefix='/api/v1/admin/tier')


# ═══ Feature → Tier Management ═══════════════════════════════════════════════

@api_tier_admin_bp.route('/features')
@admin_required
def list_features():
    """List all feature tier configs."""
    from app.helpers.tier_config import get_all_features
    features = get_all_features()
    return jsonify({'features': [f.to_dict() for f in features]})


@api_tier_admin_bp.route('/features/<slug>', methods=['POST'])
@admin_required
def update_feature(slug):
    """Update a feature's tier assignment."""
    from app.models.subscription import FeatureTierConfig
    from app.extensions import db
    from app.helpers.tier_config import TIER_LEVELS

    feat = FeatureTierConfig.query.filter_by(feature_slug=slug).first_or_404()
    data = request.get_json(silent=True) or {}

    if 'min_tier' in data:
        new_tier = data['min_tier']
        if new_tier not in TIER_LEVELS:
            return jsonify({'error': f'Invalid tier: {new_tier}'}), 400
        feat.min_tier = new_tier

    if 'is_active' in data:
        feat.is_active = bool(data['is_active'])

    if 'feature_label' in data:
        feat.feature_label = data['feature_label']

    if 'category' in data:
        feat.category = data['category']

    db.session.commit()
    return jsonify(feat.to_dict())


@api_tier_admin_bp.route('/features/bulk', methods=['POST'])
@admin_required
def bulk_update_features():
    """Bulk update feature tiers. Body: {updates: [{slug, min_tier}, ...]}"""
    from app.models.subscription import FeatureTierConfig
    from app.extensions import db
    from app.helpers.tier_config import TIER_LEVELS

    data = request.get_json(silent=True) or {}
    updates = data.get('updates', [])
    updated = 0

    for item in updates:
        slug = item.get('slug')
        new_tier = item.get('min_tier')
        if not slug or not new_tier or new_tier not in TIER_LEVELS:
            continue
        feat = FeatureTierConfig.query.filter_by(feature_slug=slug).first()
        if feat:
            feat.min_tier = new_tier
            updated += 1

    db.session.commit()
    return jsonify({'updated': updated})


# ═══ Tier Pricing Management ═════════════════════════════════════════════════

@api_tier_admin_bp.route('/pricing')
@admin_required
def list_pricing():
    """List all tier pricing."""
    from app.helpers.tier_config import get_tier_pricing
    pricing = get_tier_pricing()
    return jsonify({'pricing': [p.to_dict() for p in pricing]})


@api_tier_admin_bp.route('/pricing/<tier>', methods=['POST'])
@admin_required
def update_pricing(tier):
    """Update tier pricing."""
    from app.models.subscription import TierPricing
    from app.extensions import db

    tp = TierPricing.query.filter_by(tier=tier).first_or_404()
    data = request.get_json(silent=True) or {}

    if 'price_monthly_idr' in data:
        tp.price_monthly_idr = int(data['price_monthly_idr'])
    if 'price_yearly_idr' in data:
        tp.price_yearly_idr = int(data['price_yearly_idr'])
    if 'label' in data:
        tp.label = data['label']
    if 'description' in data:
        tp.description = data['description']
    if 'is_active' in data:
        tp.is_active = bool(data['is_active'])

    tp.updated_at = datetime.utcnow()
    db.session.commit()
    return jsonify(tp.to_dict())


# ═══ QRIS Image Upload ══════════════════════════════════════════════════════

@api_tier_admin_bp.route('/qris', methods=['POST'])
@admin_required
def upload_qris():
    """Upload QRIS payment image."""
    from app.models.settings import AppSettings
    from app.extensions import db

    if 'qris' not in request.files:
        return jsonify({'error': 'No file provided'}), 400

    f = request.files['qris']
    if not f.filename:
        return jsonify({'error': 'No file selected'}), 400

    ext = f.filename.rsplit('.', 1)[-1].lower() if '.' in f.filename else ''
    if ext not in ('png', 'jpg', 'jpeg', 'webp'):
        return jsonify({'error': 'Invalid file type'}), 400

    filename = secure_filename(f'qris.{ext}')
    upload_dir = os.path.join(current_app.static_folder, 'uploads')
    os.makedirs(upload_dir, exist_ok=True)
    filepath = os.path.join(upload_dir, filename)
    f.save(filepath)

    url = f'/static/uploads/{filename}'
    AppSettings.set('qris_image_url', url)
    db.session.commit()

    return jsonify({'qris_url': url})


@api_tier_admin_bp.route('/qris')
@admin_required
def get_qris():
    """Get current QRIS image URL."""
    from app.models.settings import AppSettings
    url = AppSettings.get('qris_image_url', '')
    return jsonify({'qris_url': url})


# ═══ Payment Verification ════════════════════════════════════════════════════

@api_tier_admin_bp.route('/payments')
@admin_required
def list_payments():
    """List subscription payments. ?status=pending|verified|rejected|all"""
    from app.models.subscription import SubscriptionPayment

    status = request.args.get('status', 'pending')
    q = SubscriptionPayment.query

    if status != 'all':
        q = q.filter_by(status=status)

    payments = q.order_by(SubscriptionPayment.created_at.desc()).limit(100).all()
    return jsonify({'payments': [p.to_dict() for p in payments]})


@api_tier_admin_bp.route('/payments/<int:payment_id>/approve', methods=['POST'])
@admin_required
def approve(payment_id):
    """Approve payment → upgrade user."""
    from app.helpers.tier_config import approve_payment
    from app.models.admin import Admin

    admin = current_user._get_current_object()
    admin_id = admin.id if isinstance(admin, Admin) else None

    result = approve_payment(payment_id, admin_id)
    if not result:
        return jsonify({'error': 'Payment not found or already processed'}), 404
    return jsonify(result)


@api_tier_admin_bp.route('/payments/<int:payment_id>/reject', methods=['POST'])
@admin_required
def reject(payment_id):
    """Reject payment with optional reason."""
    from app.helpers.tier_config import reject_payment
    from app.models.admin import Admin

    admin = current_user._get_current_object()
    admin_id = admin.id if isinstance(admin, Admin) else None

    data = request.get_json(silent=True) or {}
    reason = data.get('reason', '')

    result = reject_payment(payment_id, admin_id, reason)
    if not result:
        return jsonify({'error': 'Payment not found or already processed'}), 404
    return jsonify(result)


# ═══ User Tier Direct Assignment ═════════════════════════════════════════════

@api_tier_admin_bp.route('/users/<int:user_id>/tier', methods=['POST'])
@admin_required
def set_user_tier(user_id):
    """Admin directly sets a user's tier (bypassing payment)."""
    from app.models.user import User
    from app.models.subscription import Subscription
    from app.models.admin import Admin
    from app.extensions import db
    from app.helpers.tier_config import TIER_LEVELS

    data = request.get_json(silent=True) or {}
    new_tier = data.get('tier', 'free')
    if new_tier not in TIER_LEVELS:
        return jsonify({'error': f'Invalid tier: {new_tier}'}), 400

    user = User.query.get_or_404(user_id)
    old_tier = user.subscription_tier
    user.subscription_tier = new_tier

    admin = current_user._get_current_object()
    admin_id = admin.id if isinstance(admin, Admin) else None

    # Create subscription history record
    sub = Subscription(
        user_id=user.id,
        tier=new_tier,
        billing_cycle='manual',
        status='active',
        assigned_by=admin_id,
        notes=f'Direct assignment by admin (was {old_tier})',
    )
    db.session.add(sub)
    db.session.commit()

    return jsonify({
        'ok': True,
        'user_id': user.id,
        'old_tier': old_tier,
        'new_tier': new_tier,
    })
