"""Client download management - upload builds, serve downloads."""
import os
from pathlib import Path

from flask import request, jsonify, send_from_directory, current_app

from app.api import api_bp

# Supported platforms and their file extensions
PLATFORMS = {
    'linux': {'name': 'Linux', 'icon': 'pi-desktop', 'extensions': ['.AppImage', '.deb', '']},
    'windows': {'name': 'Windows', 'icon': 'pi-microsoft', 'extensions': ['.msi', '.exe']},
    'mac': {'name': 'macOS', 'icon': 'pi-apple', 'extensions': ['.dmg']},
    'android': {'name': 'Android', 'icon': 'pi-android', 'extensions': ['.apk']},
    'ios': {'name': 'iOS', 'icon': 'pi-apple', 'extensions': ['.ipa']},
}


def _clients_dir():
    """Get the client downloads directory."""
    base = Path(current_app.config.get('UPLOAD_PATH', '/app/data/files')).parent
    d = base / 'client-downloads'
    d.mkdir(parents=True, exist_ok=True)
    return d


def _verify_build_token():
    """Verify the build upload token from header or query param."""
    expected = os.environ.get('SECRET_KEY', '')
    if not expected:
        return False
    token = request.headers.get('X-Build-Token', '') or request.args.get('build_token', '')
    return token == expected


# --- Public: list available clients ---

@api_bp.route('/clients', methods=['GET'])
def list_clients():
    """List available client downloads (public, no auth needed)."""
    clients_dir = _clients_dir()
    available = []

    for platform, info in PLATFORMS.items():
        platform_dir = clients_dir / platform
        if not platform_dir.exists():
            continue

        files = sorted(platform_dir.iterdir(), key=lambda f: f.stat().st_mtime, reverse=True)
        if not files:
            continue

        # Take the newest file
        latest = files[0]
        available.append({
            'platform': platform,
            'name': info['name'],
            'icon': info['icon'],
            'filename': latest.name,
            'size': latest.stat().st_size,
            'updated_at': latest.stat().st_mtime,
            'download_url': f'/api/clients/{platform}/download',
        })

    return jsonify({
        'clients': available,
        'has_clients': len(available) > 0,
    }), 200


@api_bp.route('/clients/<platform>/download', methods=['GET'])
def download_client(platform):
    """Download the latest client for a platform (public, no auth)."""
    if platform not in PLATFORMS:
        return jsonify({'error': 'Unbekannte Plattform'}), 404

    clients_dir = _clients_dir()
    platform_dir = clients_dir / platform

    if not platform_dir.exists():
        return jsonify({'error': 'Kein Client fuer diese Plattform verfuegbar'}), 404

    files = sorted(platform_dir.iterdir(), key=lambda f: f.stat().st_mtime, reverse=True)
    if not files:
        return jsonify({'error': 'Kein Client verfuegbar'}), 404

    latest = files[0]
    return send_from_directory(str(platform_dir), latest.name, as_attachment=True)


# --- Build upload (authenticated with BUILD_UPLOAD_TOKEN) ---

@api_bp.route('/clients/<platform>/upload', methods=['POST'])
def upload_client(platform):
    """Upload a new client build. Authenticated with BUILD_UPLOAD_TOKEN."""
    if not _verify_build_token():
        return jsonify({'error': 'Ungueltiger Build-Token'}), 403

    if platform not in PLATFORMS:
        return jsonify({'error': 'Unbekannte Plattform'}), 404

    if 'file' not in request.files:
        return jsonify({'error': 'Keine Datei gesendet'}), 400

    upload = request.files['file']
    if not upload.filename:
        return jsonify({'error': 'Leerer Dateiname'}), 400

    clients_dir = _clients_dir()
    platform_dir = clients_dir / platform
    platform_dir.mkdir(parents=True, exist_ok=True)

    # Remove old files for this platform (keep only latest)
    for old_file in platform_dir.iterdir():
        old_file.unlink()

    dest = platform_dir / upload.filename
    upload.save(str(dest))

    return jsonify({
        'message': f'{PLATFORMS[platform]["name"]} Client hochgeladen',
        'filename': upload.filename,
        'size': dest.stat().st_size,
    }), 200
