"""Step definitions for BPM Display and Filtering feature."""
import struct
import math

import requests

from behave import given, when, then


def _make_wav_with_bpm(sr=44100, bits=16, channels=1, duration=2.0):
    num_samples = int(sr * duration)
    samples = b''.join(
        struct.pack('<h', int(math.sin(2 * math.pi * 440 * i / sr) * 0.3 * 32767))
        for i in range(num_samples)
    )
    ds = len(samples)
    buf = bytearray()
    buf += b'RIFF' + struct.pack('<I', 36 + ds) + b'WAVE'
    buf += b'fmt ' + struct.pack('<I', 16) + struct.pack('<H', 1) + struct.pack('<H', channels)
    buf += struct.pack('<I', sr) + struct.pack('<I', sr * channels * bits // 8)
    buf += struct.pack('<H', channels * bits // 8) + struct.pack('<H', bits)
    buf += b'data' + struct.pack('<I', ds) + samples
    return bytes(buf)


@given('a sample has been analyzed with BPM {bpm}')
def sample_analyzed_bpm(context, bpm):
    context.audio_data = _make_wav_with_bpm()
    context.audio_name = 'bpm_test.wav'
    resp = requests.post(
        f'{context.base_url}/api/analyze',
        files={'file': (context.audio_name, context.audio_data, 'audio/wav')},
    )
    assert resp.ok
    context.result = resp.json()


@given('samples with different BPM values are displayed')
def samples_different_bpm(context):
    pass


@given('the list is filtered by BPM 120')
def list_filtered_bpm(context):
    pass


@when('the sample card renders')
def sample_card_renders(context):
    pass


@when('I click the "{bpm} BPM" badge')
def click_bpm_badge(context, bpm):
    pass


@when('I click the "{bpm} BPM" badge again')
def click_bpm_badge_again(context, bpm):
    pass


@then('the BPM badge shows "{text}"')
def bpm_badge_shows(context, text):
    pass


@then('only samples with BPM 120 are shown')
def only_bpm_samples(context):
    pass


@then('the BPM filter range updates to 120')
def bpm_filter_updates(context):
    pass


@then('all samples are shown again')
def all_samples_shown(context):
    pass
