"""Flask API for APNG Lip Sync Tool."""
import os
import json
from pathlib import Path
from flask import Flask, request, jsonify, send_file
from werkzeug.utils import secure_filename

from .config import UPLOADS_DIR, CHARACTERS_DIR, OUTPUT_DIR, VISEME_SET
from .gemini_client import analyze_face_image, generate_viseme_image

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB max

ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}


def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/api/health', methods=['GET'])
def health_check():
    """Health check endpoint."""
    return jsonify({'status': 'ok', 'message': 'APNG Lip Sync API is running'})


@app.route('/api/upload', methods=['POST'])
def upload_image():
    """Upload an image for processing."""
    if 'image' not in request.files:
        return jsonify({'error': 'No image file provided'}), 400

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

    if not allowed_file(file.filename):
        return jsonify({'error': 'Invalid file type'}), 400

    filename = secure_filename(file.filename)
    timestamp = int(os.time() * 1000) if hasattr(os, 'time') else int(__import__('time').time() * 1000)
    unique_filename = f"{timestamp}_{filename}"
    filepath = UPLOADS_DIR / unique_filename

    file.save(filepath)

    return jsonify({
        'success': True,
        'filename': unique_filename,
        'path': str(filepath)
    })


@app.route('/api/analyze', methods=['POST'])
def analyze_image():
    """Analyze an uploaded face image."""
    data = request.get_json()
    if not data or 'filename' not in data:
        return jsonify({'error': 'No filename provided'}), 400

    filepath = UPLOADS_DIR / data['filename']
    if not filepath.exists():
        return jsonify({'error': 'File not found'}), 404

    try:
        result = analyze_face_image(filepath)
        return jsonify({
            'success': True,
            'analysis': result['analysis'],
            'filename': data['filename']
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/api/generate-visemes', methods=['POST'])
def generate_all_visemes():
    """Generate all viseme images for a character."""
    data = request.get_json()
    if not data or 'filename' not in data:
        return jsonify({'error': 'No filename provided'}), 400

    character_name = data.get('character_name', 'unnamed')
    filepath = UPLOADS_DIR / data['filename']

    if not filepath.exists():
        return jsonify({'error': 'File not found'}), 404

    # Create character directory
    char_dir = CHARACTERS_DIR / character_name
    char_dir.mkdir(parents=True, exist_ok=True)

    # Copy original as rest pose
    import shutil
    rest_path = char_dir / "rest.png"
    shutil.copy(filepath, rest_path)

    generated = {'rest': str(rest_path)}
    errors = []

    # Generate each viseme
    for viseme, description in VISEME_SET.items():
        if viseme == 'rest':
            continue

        output_path = char_dir / f"{viseme}.png"
        try:
            generate_viseme_image(
                original_image_path=filepath,
                viseme=viseme,
                viseme_description=description,
                output_path=output_path
            )
            generated[viseme] = str(output_path)
        except Exception as e:
            errors.append({'viseme': viseme, 'error': str(e)})

    # Save character config
    config = {
        'name': character_name,
        'original_image': data['filename'],
        'visemes': generated,
        'errors': errors
    }

    config_path = char_dir / 'config.json'
    with open(config_path, 'w') as f:
        json.dump(config, f, indent=2)

    return jsonify({
        'success': True,
        'character_name': character_name,
        'generated': list(generated.keys()),
        'errors': errors
    })


@app.route('/api/characters', methods=['GET'])
def list_characters():
    """List all saved characters."""
    characters = []

    if CHARACTERS_DIR.exists():
        for char_dir in CHARACTERS_DIR.iterdir():
            if char_dir.is_dir():
                config_path = char_dir / 'config.json'
                if config_path.exists():
                    with open(config_path) as f:
                        config = json.load(f)
                    characters.append({
                        'name': config.get('name', char_dir.name),
                        'directory': char_dir.name,
                        'visemes': list(config.get('visemes', {}).keys())
                    })

    return jsonify({'characters': characters})


@app.route('/api/characters/<name>/viseme/<viseme>', methods=['GET'])
def get_viseme_image(name, viseme):
    """Get a specific viseme image for a character."""
    char_dir = CHARACTERS_DIR / name
    image_path = char_dir / f"{viseme}.png"

    if not image_path.exists():
        return jsonify({'error': 'Viseme image not found'}), 404

    return send_file(image_path, mimetype='image/png')


@app.route('/api/viseme-set', methods=['GET'])
def get_viseme_set():
    """Get the list of available visemes."""
    return jsonify({'visemes': VISEME_SET})


if __name__ == '__main__':
    app.run(debug=True, port=5000)
