<#@ template language="C#" HostSpecific="True" #>
<#@ output extension="cs" #>
<#@ include file="EditHead.include.t4" #>
<#@ parameter name="GetSqlExceptionMethodName" type="System.String" #>
<#@ parameter name="GetExceptionMessageMethodName" type="System.String" #>
<#@ parameter name="ArrayToStringMethodName" type="System.String" #>
<#@ parameter name="ReloadOnBatchError" type="System.Boolean" #>
<#
	// CreateActionUrl
	if(!string.IsNullOrEmpty(CreateActionUrl))
	{
#>
        public ActionResult <#= CreateActionUrl #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return <#= CreateMethodName #>(requestData, <#= DbContextName #>.<#= EntitySetName #>);
        }

        private ActionResult <#= CreateMethodName #><T>(CollectionViewEditRequest<T> requestData, DbSet<T> data) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    data.Add(item);
                    <#= DbContextName #>.SaveChanges();
                }
                catch (Exception e)
                {
                    error = <#= GetExceptionMessageMethodName #>(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// UpdateActionUrl
	if(!string.IsNullOrEmpty(UpdateActionUrl))
	{
#>
        public ActionResult <#= UpdateActionUrl #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return <#= UpdateMethodName #>(requestData, <#= DbContextName #>.<#= EntitySetName #>);
        }

        private ActionResult <#= UpdateMethodName #><T>(CollectionViewEditRequest<T> requestData, DbSet<T> data) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    <#= DbContextName #>.Entry(item as object).State = EntityState.Modified;
                    <#= DbContextName #>.SaveChanges();
                }
                catch (Exception e)
                {
                    error = <#= GetExceptionMessageMethodName #>(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// DeleteActionUrl
	if(!string.IsNullOrEmpty(DeleteActionUrl))
	{
#>
        public ActionResult <#= DeleteActionUrl #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return <#= DeleteMethodName #>(requestData, <#= DbContextName #>.<#= EntitySetName #>, item => new object[] { <#= PrimaryKeys #> });
        }

        private ActionResult <#= DeleteMethodName #><T>(CollectionViewEditRequest<T> requestData, DbSet<T> data, Func<T, object[]> getKeys) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    T resultItem = null;
                    foreach (var i in data)
                    {
                        if (string.Equals(<#= ArrayToStringMethodName #>(getKeys(i)), <#= ArrayToStringMethodName #>(getKeys(item))))
                        {
                            resultItem = i;
                            break;
                        }
                    }

                    data.Remove(resultItem);
                    <#= DbContextName #>.SaveChanges();
                }
                catch (Exception e)
                {
                    error = <#= GetExceptionMessageMethodName #>(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// BatchEditActionUrl
	if(!string.IsNullOrEmpty(BatchEditActionUrl))
	{
#>
        public ActionResult <#= BatchEditActionUrl #>([C1JsonRequest]CollectionViewBatchEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            Func<<#= ViewDataTypeName #>, object[]> getKeys = item => new object[] { <#= PrimaryKeys #> };
            return this.C1Json(CollectionViewHelper.BatchEdit(requestData, batchData =>
            {
                var itemresults = new List<CollectionViewItemResult<<#= ViewDataTypeName #>>>();
                string error = string.Empty;
                bool success = true;
                try
                {
                    if (batchData.ItemsCreated != null)
                    {
                        batchData.ItemsCreated.ToList().ForEach(st =>
                        {
                            <#= DbContextName #>.<#= EntitySetName #>.Add(st);
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = st
                            });
                        });
                    }
                    if (batchData.ItemsDeleted != null)
                    {
                        batchData.ItemsDeleted.ToList().ForEach(item =>
                        {
                            <#= ViewDataTypeName #> fItem = null;
                            foreach (var i in <#= DbContextName #>.<#= EntitySetName #>)
                            {
                                if (string.Equals(<#= ArrayToStringMethodName #>(getKeys(i)), <#= ArrayToStringMethodName #>(getKeys(item))))
                                {
                                    fItem = i;
                                    break;
                                }
                            }

                            <#= DbContextName #>.<#= EntitySetName #>.Remove(fItem);
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = item
                            });
                        });
                    }
                    if (batchData.ItemsUpdated != null)
                    {
                        batchData.ItemsUpdated.ToList().ForEach(item =>
                        {
                            <#= DbContextName #>.Entry(item).State = EntityState.Modified;
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = item
                            });
                        });
                    }
                    <#= DbContextName #>.SaveChanges();
                }
                catch (Exception e)
                {
                    error = <#= GetExceptionMessageMethodName #>(e);
                    success = false;
<#
		if(ReloadOnBatchError)
		{
#>
                    try
                    {
                        var refreshableObjects = <#= DbContextName #>.ChangeTracker.Entries().Where(c => c.State == EntityState.Modified).ToList();
                        refreshableObjects.ForEach(o => o.Reload());
                    }
                    catch (Exception er)
                    {
                        error = error + Environment.NewLine + er.Message;
                    }
<#
		}
#>
                }
 
                return new CollectionViewResponse<<#= ViewDataTypeName #>>
                {
                    Error = error,
                    Success = success,
                    OperatedItemResults = itemresults
                };
            }, () => <#= DbContextName #>.<#= EntitySetName #>.ToList()));
        }

<#
	}

	if(!string.IsNullOrEmpty(CreateActionUrl) || !string.IsNullOrEmpty(UpdateActionUrl) || !string.IsNullOrEmpty(DeleteActionUrl) || !string.IsNullOrEmpty(BatchEditActionUrl))
	{
#>
        /// <summary>
        /// In order to get the real exception message.
        /// </summary>
        private static SqlException <#= GetSqlExceptionMethodName #>(Exception e)
        {
            while(e != null && !(e is SqlException))
            {
                e = e.InnerException;
            }
            return e as SqlException;
        }

        // Get the real exception message
        internal static string <#= GetExceptionMessageMethodName #>(Exception e)
        {
            var msg = e.Message;
            var sqlException = <#= GetSqlExceptionMethodName #>(e);
            if (sqlException != null)
            {
                msg = sqlException.Message;
            }
            return msg;
        }
<# 
		if(!string.IsNullOrEmpty(DeleteActionUrl) || !string.IsNullOrEmpty(BatchEditActionUrl))
		{
#>

        /// <summary>
        /// Get string from object array.
        /// </summary>
        /// <param name="array">the object array</param>
        /// <returns>the string value</returns>
        private static string <#= ArrayToStringMethodName #>(object[] array)
        {
            if (array != null)
            {
                return string.Join(",", array.Cast<object>().Select(a => a.ToString()));
            }
            return "";
        }
<#
		}
	}
#>