using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web.Mvc;
using Kendo.Mvc.Grid.CRUD.Models;

namespace Kendo.Mvc.Grid.CRUD.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// Creates new products by inserting the data posted by the Kendo Grid in the database.
        /// </summary>
        /// <param name="products">The products created by the user.</param>
        /// <returns>The inserted products so the Kendo Grid is aware of the database generated ProductID</returns>
        [HttpPost]
        public ActionResult CreateProduct(IEnumerable<ProductViewModel> products)
        {
            var result = new List<Product>();

            using (var northwind = new Northwind())
            {
                //Iterate all created products which are posted by the Kendo Grid
                foreach (var productViewModel in products)
                {
                    // Create a new Product entity and set its properties from productViewModel
                    var product = new Product
                    {
                        ProductName = productViewModel.ProductName,
                        UnitPrice = productViewModel.UnitPrice,
                        UnitsInStock = productViewModel.UnitsInStock,
                        Discontinued = productViewModel.Discontinued
                    };

                    // store the product in the result
                    result.Add(product);

                    // Add the entity
                    northwind.Products.AddObject(product);
                }

                // Insert all created products to the database
                northwind.SaveChanges();

                // Return the inserted products - the Kendo Grid needs their ProductID which is generated by SQL server during insertion

                return Json(result.Select(p => new ProductViewModel
                {
                    ProductID = p.ProductID,
                    ProductName = p.ProductName,
                    UnitPrice = p.UnitPrice,
                    UnitsInStock = p.UnitsInStock,
                    Discontinued = p.Discontinued
                })
                .ToList());
            }
        }

        /// <summary>
        /// Reads the available products to provide data for the Kendo Grid
        /// </summary>
        /// <returns>All available products as JSON</returns>
        [HttpPost]
        public ActionResult GetProducts()
        {
            using (var northwind = new Northwind())
            {
                var products = northwind.Products
                    // Use a view model to avoid serializing internal Entity Framework properties as JSON
                    .Select(p => new ProductViewModel
                    {
                        ProductID = p.ProductID,
                        ProductName = p.ProductName,
                        UnitPrice = p.UnitPrice,
                        UnitsInStock = p.UnitsInStock,
                        Discontinued = p.Discontinued
                    })
                    .OrderBy(p => p.ProductName)
                    .ToList();

                return Json(products);
            }
        }

        /// <summary>
        /// Updates existing products by updating the database with the data posted by the Kendo Grid.
        /// </summary>
        /// <param name="products">The products updated by the user</param>
        [HttpPost]
        public ActionResult UpdateProduct(IEnumerable<ProductViewModel> products)
        {
            using (var northwind = new Northwind())
            {
                //Iterate all updated products which are posted by the Kendo Grid
                foreach (var productViewModel in products)
                {
                    // Create a new Product entity and set its properties from productViewModel
                    var product = new Product
                    {
                        ProductID = (int)productViewModel.ProductID,
                        ProductName = productViewModel.ProductName,
                        UnitPrice = productViewModel.UnitPrice,
                        UnitsInStock = productViewModel.UnitsInStock,
                        Discontinued = productViewModel.Discontinued
                    };

                    // Attach the entity
                    northwind.Products.Attach(product);
                    // Change its state to Modified so Entity Framework can update the existing product instead of creating a new one
                    northwind.ObjectStateManager.ChangeObjectState(product, EntityState.Modified);
                }

                // Save all updated products to the database
                northwind.SaveChanges();

                //Return emtpy result
                return Json(null);
            }
        }

        /// <summary>
        /// Destroys existing products by deleting them from the database.
        /// </summary>
        /// <param name="productId">The products deleted by the user</param>
        [HttpPost]
        public ActionResult DeleteProduct(int productId)
        {
            using (var northwind = new Northwind())
            {
                var p = new Product { ProductID = productId };
                northwind.Products.Attach(p);
                northwind.Products.DeleteObject(p);
                northwind.SaveChanges();
                return Json(null);
            }
        }

    }
}