import argparse
import tempfile
from pathlib import Path

import joblib

from audio_utils import SUPPORTED_AUDIO_EXTENSIONS, convert_to_wav
from features import LABEL_PD, LABEL_TPD, extract_features


BASE_DIR = Path(__file__).resolve().parent
MODEL_PATH = BASE_DIR / "models" / "svm_voice_confidence_model.joblib"
CONFIDENCE_THRESHOLD = 0.60

LABEL_DESCRIPTION = {
    LABEL_PD: "Percaya Diri",
    LABEL_TPD: "Tidak Percaya Diri",
}


def prepare_audio_for_prediction(audio_path):
    """
    Menyiapkan audio prediksi menjadi WAV mono 22050 Hz.
    Path hasil konversi dikembalikan bersama flag apakah file temporer perlu dihapus.
    """
    audio_path = Path(audio_path)
    extension = audio_path.suffix.lower()

    if extension not in SUPPORTED_AUDIO_EXTENSIONS:
        allowed = ", ".join(sorted(SUPPORTED_AUDIO_EXTENSIONS))
        raise ValueError(f"Format audio tidak didukung: {extension}. Format yang didukung: {allowed}")

    temp_wav_path = Path(tempfile.NamedTemporaryFile(delete=False, suffix=".wav").name)
    convert_to_wav(audio_path, temp_wav_path)
    return temp_wav_path


def predict_audio(audio_path, model_path=MODEL_PATH):
    """
    Memprediksi satu file audio.
    Audio diproses dengan preprocessing dan ekstraksi fitur yang sama seperti training.
    """
    model = joblib.load(model_path)

    temp_wav_path = prepare_audio_for_prediction(audio_path)
    try:
        features = extract_features(temp_wav_path).reshape(1, -1)
        predicted_label = model.predict(features)[0]
        probabilities = model.predict_proba(features)[0]
        class_probabilities = dict(zip(model.classes_, probabilities))
        confidence = class_probabilities[predicted_label]
    finally:
        temp_wav_path.unlink(missing_ok=True)

    return predicted_label, LABEL_DESCRIPTION[predicted_label], confidence, class_probabilities


def main():
    parser = argparse.ArgumentParser(description="Prediksi tingkat percaya diri dari audio")
    parser.add_argument("audio_path", help="Path file audio yang ingin diprediksi")
    args = parser.parse_args()

    audio_path = Path(args.audio_path)
    if not audio_path.exists():
        raise FileNotFoundError(f"File tidak ditemukan: {audio_path}")

    label, description, confidence, probabilities = predict_audio(audio_path)

    probability_pd = probabilities.get(LABEL_PD, 0.0)
    probability_tpd = probabilities.get(LABEL_TPD, 0.0)

    print("=== Hasil Prediksi ===")
    print(f"File             : {audio_path}")
    print(f"Prediksi         : {label}")
    print(f"Keterangan       : {description}")
    print(f"Confidence       : {confidence * 100:.2f}%")
    print(f"Probabilitas PD  : {probability_pd * 100:.2f}%")
    print(f"Probabilitas TPD : {probability_tpd * 100:.2f}%")

    if confidence < CONFIDENCE_THRESHOLD:
        print(
            "Peringatan       : Model belum yakin, suara perlu direkam ulang "
            "atau data training perlu ditambah."
        )


if __name__ == "__main__":
    main()
