//
// Copyright (c) Double Symmetry GmbH
// Commercial use requires a license. See https://rntp.dev/pricing
//

import Foundation

@testable import PlayerCore

class MockPlayerEngine: PlayerEngine {
  var currentTime: Double = 0
  var duration: Double = 0
  var bufferedPosition: Double = 0
  var cachedPosition: Double = 0
  var defaultRate: Float = 1.0
  var currentRate: Float = 0.0
  var volume: Float = 1.0
  var isPlaying: Bool = false
  var hasCurrentItem: Bool = false

  var onPlaybackStateChange: ((EnginePlaybackState) -> Void)?
  var onItemReady: (() -> Void)?
  var onItemFailed: ((_ code: String, _ message: String) -> Void)?
  var onItemPlayedToEnd: (() -> Void)?
  var onDurationChange: (() -> Void)?
  var onTimedMetadata: ((_ metadata: StreamMetadata) -> Void)?
  var onAssetMetadata: ((_ metadata: StreamMetadata) -> Void)?

  // MARK: - Call Tracking

  private(set) var playCallCount = 0
  private(set) var pauseCallCount = 0
  private(set) var loadedURLs: [URL] = []
  private(set) var loadedHeaders: [[String: String]?] = []
  private(set) var seekTargets: [TimeInterval] = []
  private(set) var resetCallCount = 0

  func play() {
    playCallCount += 1
  }

  func pause() {
    pauseCallCount += 1
  }

  func load(url: URL, headers: [String: String]? = nil, isLive: Bool = false) {
    loadedURLs.append(url)
    loadedHeaders.append(headers)
    hasCurrentItem = true
  }

  func seek(to seconds: TimeInterval, completion: @escaping (Bool) -> Void) {
    seekTargets.append(seconds)
    currentTime = seconds
    completion(true)
  }

  func reset() {
    resetCallCount += 1
    hasCurrentItem = false
    isPlaying = false
  }

  // MARK: - Test Simulation

  func simulatePlaybackState(_ state: EnginePlaybackState) {
    if state == .playing { isPlaying = true }
    else { isPlaying = false }
    onPlaybackStateChange?(state)
  }

  func simulateItemReady() {
    onItemReady?()
  }

  func simulateItemFailed(code: String = "test_error", message: String = "Test playback error") {
    onItemFailed?(code, message)
  }

  func simulatePlayedToEnd() {
    onItemPlayedToEnd?()
  }

  func simulateDurationChange(_ newDuration: Double) {
    duration = newDuration
    onDurationChange?()
  }

  func simulateTimedMetadata(_ metadata: StreamMetadata) {
    onTimedMetadata?(metadata)
  }

  func simulateTimedMetadata(title: String?, artist: String?) {
    simulateTimedMetadata(StreamMetadata(title: title, artist: artist, albumTitle: nil, artworkUri: nil, genre: nil))
  }
}
