using System;
using System.IO;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Util;
using Android.Widget;
using Google.Android.Material.Dialog;
using KeePass.DataExchange;
using KeePass.DataExchange.Formats;
using KeePassLib.Interfaces;
using KeePassLib.Serialization;
using keepass2android.Io;
using keepass2android;

namespace keepass2android
{
    public class ExportDbProcessManager: FileSaveProcessManager
    {
        private readonly FileFormatProvider _ffp;

        public ExportDbProcessManager(int requestCode, Activity activity, FileFormatProvider ffp) : base(requestCode, activity)
        {
            _ffp = ffp;
        }

        protected override void SaveFile(IOConnectionInfo ioc)
        {
            var exportDb = new ExportDatabaseActivity.ExportDb(_activity, App.Kp2a, new ActionOnFinish(_activity, (success, message, activity) =>
                {
                    if (!success)
                        Toast.MakeText(activity, message, ToastLength.Long).Show();
                    else
                        Toast.MakeText(activity, _activity.GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
                    activity.Finish();
                }
            ), _ffp, ioc);
            ProgressTask pt = new ProgressTask(App.Kp2a, _activity, exportDb);
            pt.Run();

        }
    }

	[Activity(Label = "@string/app_name",
	    ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden,
        Theme = "@style/Kp2aTheme_ActionBar", Exported = true)]
	[IntentFilter(new[] {"kp2a.action.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})]
	public class ExportDatabaseActivity : LockCloseActivity
	{
		FileFormatProvider[] _ffp = new FileFormatProvider[]
			{
				new KeePassKdb2x(),
				new KeePassXml2x(), 
				new KeePassCsv1x()
			};

		private int _fileFormatIndex;

	    private ExportDbProcessManager _exportDbProcessManager;

        protected override void OnCreate(Android.OS.Bundle savedInstanceState)
		{
			base.OnCreate(savedInstanceState);
			MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
			builder.SetTitle(Resource.String.export_fileformats_title);
			builder.SetSingleChoiceItems(Resource.Array.export_fileformat_options, _fileFormatIndex,
				delegate(object sender, DialogClickEventArgs args) { _fileFormatIndex = args.Which; });
			builder.SetPositiveButton(Android.Resource.String.Ok, delegate
			{
			    _exportDbProcessManager = new ExportDbProcessManager(0, this, _ffp[_fileFormatIndex]);
			    _exportDbProcessManager.StartProcess();
			});
			builder.SetNegativeButton(Resource.String.cancel, delegate {
					Finish();
				});
			builder.Show();
		}

		protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
		{
			base.OnActivityResult(requestCode, resultCode, data);

		    if (_exportDbProcessManager?.OnActivityResult(requestCode, resultCode, data) == true)
		        return;

			Finish();

		}
        

		protected int RequestCodeDbFilename
		{
			get { return 0; }
		}

		public class ExportDb : RunnableOnFinish
		{
			private readonly IKp2aApp _app;
			private readonly FileFormatProvider _fileFormat;
			private IOConnectionInfo _targetIoc;

			public ExportDb(Activity activity, IKp2aApp app, OnFinish onFinish, FileFormatProvider fileFormat, IOConnectionInfo targetIoc) : base(activity, onFinish)
			{
				_app = app;
				this._fileFormat = fileFormat;
				_targetIoc = targetIoc;
			}

			public override void Run()
			{
				StatusLogger.UpdateMessage(UiStringKey.exporting_database);
				var pd = _app.CurrentDb.KpDatabase;
				PwExportInfo pwInfo = new PwExportInfo(pd.RootGroup, pd, true);
				
				try
				{
					var fileStorage = _app.GetFileStorage(_targetIoc);
					if (fileStorage is IOfflineSwitchable)
					{
						((IOfflineSwitchable) fileStorage).IsOffline = false;
					}
					using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
					{
						Stream sOut = writeTransaction.OpenFile();
						_fileFormat.Export(pwInfo, sOut, new NullStatusLogger());
						
						if (sOut != null) sOut.Close();

						writeTransaction.CommitWrite();
						
					}
					if (fileStorage is IOfflineSwitchable)
					{
						((IOfflineSwitchable)fileStorage).IsOffline = App.Kp2a.OfflineMode;
					}
					
					Finish(true);

					
				}
				catch (Exception ex)
				{
					Finish(false, ex.Message);
				}


			}
		}

	}
}