@Observable class ApplicationData {
   var playing: Bool = false
   var progress: CGFloat = 0
   @ObservationIgnored var customVideoView: PlayerView!
   @ObservationIgnored var viewData: ViewData

   static let shared: ApplicationData = ApplicationData()
   private init() {
      customVideoView = PlayerView()
      viewData = ViewData()

      let bundle = Bundle.main
      let videoURL = bundle.url(forResource: "videotrees", withExtension: "mp4")
      let asset = AVURLAsset(url: videoURL!)
      viewData.playerItem = AVPlayerItem(asset: asset)
      viewData.player = AVPlayer(playerItem: viewData.playerItem)

      Task {
         await MainActor.run {
            viewData.playerLayer = customVideoView.view.layer as? AVPlayerLayer
            viewData.playerLayer?.player = viewData.player
         }
         let interval = CMTime(value: 1, timescale: 2)
         viewData.player?.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { time in
            Task { @MainActor in
               if let duration = self.viewData.playerItem?.duration {
                  let position = time.seconds / duration.seconds
                  self.progress = CGFloat(position)
               }
            }
         })
         await rewindVideo()
      }
   }
   func rewindVideo() async {
      let center = NotificationCenter.default
      let name = NSNotification.Name.AVPlayerItemDidPlayToEndTime
      for await _ in center.notifications(named: name, object: nil) {
         if let finished = await viewData.playerItem?.seek(to: CMTime.zero), finished {
            await MainActor.run {
               playing = false
               progress = 0
            }
         }
      }
   }
   func playVideo() {
      if viewData.playerItem?.status == .readyToPlay {
         if playing {
            viewData.player?.pause()
            playing = false
         } else {
            viewData.player?.play()
            playing = true
         }
      }
   }
}