/*
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC.
 */

using Android.Media;
using Android.Views;
using Android.Widget;
using Android.Content;

using AndroidX.CoordinatorLayout.Widget;

using DXLib.Video;
using DXLib.Video.Source;

using Uri = Android.Net.Uri;
using Color = Android.Graphics.Color;

namespace iStatVball3.Platforms.Android.DXLib.Video;

/*
 * iOS native implementation of video player API based on AVPlayer.
 */
public sealed class DXVideoPlayer : CoordinatorLayout, MediaPlayer.IOnPreparedListener
{
    /* Fields */
    private VideoView _videoView;
    
    private MediaController _mediaController;
    private MediaPlayer _mediaPlayer;
    
    private bool _isPrepared;
    private readonly Context _context;

    private DXVideo _video;

    /* Methods */
    public DXVideoPlayer( Context context, DXVideo video ) : base( context )
    {
        _context = context;
        _video = video;

        SetBackgroundColor( Color.Black );

        // Create RelativeLayout for sizing video
        RelativeLayout relativeLayout = new( _context )
        {
            LayoutParameters = new LayoutParams( ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent )
            {
                Gravity = (int) GravityFlags.Center
            }
        };

        // Create VideoView and position in RelativeLayout
        _videoView = new VideoView( context )
        {
            LayoutParameters = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent )
        };

        // Add to layouts
        relativeLayout.AddView( _videoView );
        AddView( relativeLayout );

        // Register for events
        _videoView.Prepared += OnVideoViewPrepared;
    }

    // Release all native resources
    protected override void Dispose( bool disposing )
    {
        if ( disposing )
        {
            _videoView.Prepared -= OnVideoViewPrepared;
            _videoView.Dispose();
            _videoView = null;
            _video = null;
        }

        base.Dispose( disposing );
    }

    // PROPERTY HANDLING
    public void UpdateTransportControlsEnabled()
    {
        if ( _video.ShowControls )
        {
            _mediaController = new MediaController( _context );
            
            _mediaController.SetMediaPlayer( _videoView );
            _videoView.SetMediaController( _mediaController );
        }
        else
        {
            _videoView.SetMediaController( null );
            
            if ( _mediaController != null )
            {
                _mediaController.SetMediaPlayer( null );
                _mediaController = null;
            }
        }
    }

    public void UpdateSource()
    {
        _isPrepared = false;
        bool hasSetSource = false;

        switch ( _video.Source )
        {
            case DXUriVideoSource source:
            {
                string uri = source.Uri;
            
                if ( !string.IsNullOrWhiteSpace( uri ) )
                {
                    _videoView.SetVideoURI( Uri.Parse( uri ) );
                    hasSetSource = true;
                }

                break;
            }
            case DXFileVideoSource source:
            {
                string filename = source.File;
            
                if ( !string.IsNullOrWhiteSpace( filename ) )
                {
                    _videoView.SetVideoPath( filename );
                    hasSetSource = true;
                }

                break;
            }
            case DXResourceVideoSource source:
            {
                string package = Context?.PackageName;
                string path = source.Path;
            
                if ( !string.IsNullOrWhiteSpace( path ) )
                {
                    string assetFilePath = "content://" + package + "/" + path;
                    _videoView.SetVideoPath( assetFilePath );
                
                    hasSetSource = true;
                }

                break;
            }
        }

        if ( hasSetSource && _video.AutoPlay )
        {
            _videoView.Start();
        }
    }

    public void UpdateIsLooping()
    {
        _videoView.SetOnPreparedListener( _video.IsLooping ? this : null );
    }

    public void UpdatePosition()
    {
        if ( Math.Abs( _videoView.CurrentPosition - _video.Position.TotalMilliseconds ) > 1000 )
        {
            _videoView.SeekTo( (int)_video.Position.TotalMilliseconds );
        }
    }

    public void UpdateSpeed()
    {
        PlaybackParams settings = new();

        settings.SetSpeed( _video.Speed);

        if( _mediaPlayer != null )
        {
            _mediaPlayer.PlaybackParams = settings;
        }
    }

    public void UpdateStatus()
    {
        DXVideo.VideoStatus status = DXVideo.VideoStatus.NotReady;

        if ( _isPrepared )
        {
            status = _videoView.IsPlaying ? DXVideo.VideoStatus.Playing : DXVideo.VideoStatus.Paused;
        }

        ((DXVideoController)_video).Status = status;

        int position = _videoView.CurrentPosition;
        int duration = _videoView.Duration;
        
        // Set position
        _video.Position = TimeSpan.FromMilliseconds( position );
        
        // MUST set ended state here
        if ( (duration > 0) && ((duration - position) <= 0) )
        {
            ((DXVideoController)_video).Status = DXVideo.VideoStatus.Ended;
        }
    }

    // COMMAND HANDLING
    public void PlayRequested( TimeSpan position )
    {
        _videoView.Start();
    }

    public void PauseRequested( TimeSpan position )
    {
        _videoView.Pause();
    }

    public void StopRequested( TimeSpan position )
    {
        _videoView.StopPlayback();

        // Ensure video can be played again
        _videoView.Resume();
    }

    // EVENT HANDLING
    private void OnVideoViewPrepared( object sender, EventArgs args )
    {
        _isPrepared = true;
        
        ((DXVideoController)_video).Duration = TimeSpan.FromMilliseconds( _videoView.Duration );
    }

    public void OnPrepared( MediaPlayer mp )
    {
        if ( mp != null )
        {
            _mediaPlayer = mp;
            
            mp.Looping = _video.IsLooping;
        }
    }
}

//
