import random
import struct
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QTimer, QSize, QPointF
from PyQt5.QtGui import QPainter, QColor, QPen, QLinearGradient, QBrush

class WaveformWidget(QWidget):
    def __init__(self, parent=None, dynamic=False):
        super().__init__(parent)
        self.dynamic = dynamic
        self.setMinimumSize(200, 60)
        self.setMaximumHeight(80)
        self.waveform_data = [random.randint(10, 90) for _ in range(50)]
        if self.dynamic:
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.update_waveform)
            self.timer.start(100)

    def update_waveform(self):
        self.waveform_data = self.waveform_data[1:] + [random.randint(10, 90)]
        self.update()

    def set_data(self, data):
        # Convert audio data to visual amplitude
        if isinstance(data, bytes) and len(data) >= 2:
            # Extract PCM samples (16-bit signed)
            num_samples = min(len(data) // 2, 20)  # Take up to 20 samples
            samples = []
            for i in range(0, num_samples * 2, 2):
                if i + 1 < len(data):
                    sample = struct.unpack('h', data[i:i+2])[0]
                    # Normalize to 0-100 range
                    amplitude = abs(sample) / 327.68  # 32768/100
                    samples.append(min(95, max(5, amplitude)))
            
            if samples:
                # Add new samples and maintain fixed size
                self.waveform_data.extend(samples)
                # Keep last 50 samples
                self.waveform_data = self.waveform_data[-50:]
        else:
            # Fallback for non-audio data
            amplitude = sum(byte for byte in data[:20]) % 90 + 10
            self.waveform_data = self.waveform_data[1:] + [amplitude]
        
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.fillRect(self.rect(), QColor("#2D2D2D"))
        gradient = QLinearGradient(0, 0, 0, self.height())
        gradient.setColorAt(0.0, QColor("#0078D4"))
        gradient.setColorAt(1.0, QColor("#50E6A4"))
        pen = QPen(QBrush(gradient), 2)
        painter.setPen(pen)
        bar_width = self.width() / len(self.waveform_data)
        max_h = self.height() - 10
        for i, val in enumerate(self.waveform_data):
            bar_height = (val / 100.0) * max_h
            x = i * bar_width
            y = (self.height() - bar_height) / 2
            painter.drawLine(QPointF(x + bar_width / 2, y), QPointF(x + bar_width / 2, y + bar_height))

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.update()