import os
import uuid
import json
import subprocess


def _parse_url_entry(url_entry):
    if isinstance(url_entry, str):
        try:
            parsed = json.loads(url_entry)
            if isinstance(parsed, dict):
                return parsed.get("path", "")
        except (json.JSONDecodeError, TypeError):
            return url_entry
    elif isinstance(url_entry, dict):
        return url_entry.get("path", "")
    return ""


def convert(urls, target_format, options, config):
    try:
        upload_dir = config.get("UPLOAD_DIR", "static/uploads")
        ffmpeg_path = config.get("FFMPEG_PATH", "ffmpeg")

        results = []
        errors = []

        for url_entry in urls:
            file_path = _parse_url_entry(url_entry)
            if not file_path or file_path == "empty":
                continue

            try:
                full_path = os.path.join(upload_dir, file_path)
                if not os.path.exists(full_path):
                    full_path = file_path
                if not os.path.exists(full_path):
                    errors.append(f"File not found: {os.path.basename(file_path)}")
                    continue

                source_name = os.path.splitext(os.path.basename(file_path))[0]
                output_filename = f"{source_name}.mp4"

                output_folder = uuid.uuid4().hex
                output_dir = os.path.join(upload_dir, output_folder)
                os.makedirs(output_dir, exist_ok=True)

                output_path = os.path.join(output_dir, output_filename)

                cmd = [
                    ffmpeg_path, "-y",
                    "-i", full_path,
                    "-c:v", "libx264",
                    "-crf", "28",
                    "-preset", "medium",
                    "-c:a", "aac",
                    "-b:a", "96k",
                    "-movflags", "+faststart",
                    output_path
                ]

                result = subprocess.run(
                    cmd,
                    capture_output=True,
                    text=True,
                    timeout=600
                )

                if result.returncode != 0:
                    errors.append(f"FFmpeg error for {os.path.basename(file_path)}: {result.stderr[-500:] if result.stderr else 'Unknown error'}")
                    continue

                if not os.path.exists(output_path) or os.path.getsize(output_path) == 0:
                    errors.append(f"Output file was not created for {os.path.basename(file_path)}")
                    continue

                results.append(output_path)

            except subprocess.TimeoutExpired:
                errors.append(f"Compression timed out for {os.path.basename(file_path)}")
            except Exception as e:
                fname = os.path.basename(file_path) if file_path else "unknown"
                errors.append(f"Failed to compress {fname}: {str(e)}")

        if not results and errors:
            return {
                "error": True,
                "message": "; ".join(errors)
            }

        if not results and not errors:
            return {
                "error": True,
                "message": "No files were provided for compression."
            }

        return {
            "error": False,
            "results": results,
            "output_path": results[0] if results else "",
            "errors": errors if errors else None
        }

    except Exception as e:
        return {"error": True, "message": f"Compression failed: {str(e)}"}
