using FSI.Prj.Mgt.Data;
using FSI.Prj.Mgt.Models;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Newtonsoft.Json;
using X.PagedList;

namespace FSI.Prj.Mgt.Controllers
{
    public class OrganizationController : Controller
    {

        private readonly ApplicationDbContext _context;

        public OrganizationController(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<IActionResult> Index(string searchString, int? page)
        {
            await UpdateFullShortName(_context.Organizations.ToList());
            IQueryable<Organization> items = _context.Organizations.Include(x => x.Parent).OrderBy(x => x.FullShortName);

            if (!string.IsNullOrEmpty(searchString))
            {
                items = items.Where(x => x.Name!.Contains(searchString) || x.Description!.Contains(searchString));
            }

            return View(await items.ToPagedListAsync(page ?? 1, 10));




            //////List<TreeViewNode> nodes = new();

            //////// Loop and add the Parent Nodes
            //////foreach (Organization organization in _context.Organizations)
            //////{
            //////    if (organization.ParentId == null)
            //////    {
            //////        nodes.Add(new TreeViewNode
            //////        {
            //////            id = organization.Id.ToString(),
            //////            parent = "#",
            //////            text = organization.Name,
            //////        });
            //////    }
            //////    else
            //////    {
            //////        nodes.Add(new TreeViewNode
            //////        {
            //////            id = organization.Id.ToString(),
            //////            parent = organization.ParentId.ToString(),
            //////            text = organization.Name,
            //////        });
            //////    }
            //////}
            //////ViewBag.Json = JsonConvert.SerializeObject(nodes);
        }

        public async Task<IActionResult> AddOrEdit(int id = 0)
        {

            if (id == 0)
            {
                var item = new Organization();
                item.Parents = _context.Organizations.OrderBy(x => x.Name).ToList();
                item.Parents.Add(new Organization());

                if (item.ParentId == null)
                {
                    item.ParentId = 0;
                }

                return View(item);
            }
            else
            {
                var item = await _context.Organizations.FindAsync(id);

                if (item == null) // kein Fund
                {
                    return NotFound();
                }

                item.Parents = _context.Organizations.ToList();
                item.Parents.Add(new Organization()); // neue & leere Organisation einfügen
                item.Parents.Remove(item); // eingene Organisation entfernen
                item.Parents.OrderBy(x => x.Name); // sortieren

                if (item.ParentId == null)
                {
                    item.ParentId = 0;
                }

                return View(item);
            }
        }

        [HttpPost]
        public async Task<IActionResult> AddOrEdit(int id, Organization item)
        {
            ModelState.Remove("Parent");
            ModelState.Remove("Parents");
            ModelState.Remove("FullShortName");

            if (string.IsNullOrEmpty(item.FullShortName))
            {
                item.FullShortName = GetFullShortName(_context.Organizations.ToList(), item.ParentId, item.ShortName);
            }
            
            item.ModificationTimeStamp = DateTime.Now; // Zeitstempel für Modifikation 

            if (ModelState.IsValid)
            {

                if (item.ParentId == 0)
                {
                    item.ParentId = null;
                }

                if (id == 0) // Insert
                {
                    try
                    {
                        item.CreationTimeStamp = item.ModificationTimeStamp; // Zeitstempel für Erstellung
                        _context.Add(item);                        
                        await _context.SaveChangesAsync();                        
                    }
                    catch (Exception ex)
                    {

                    }
                }
                else // Update
                {
                    try
                    {                       
                        _context.Update(item);
                        await _context.SaveChangesAsync();                        
                    }
                    catch (Exception ex)
                    {

                    }
                }

                return Json(new { isValid = true, html = Helper.RenderRazorViewToString(this, "_ViewAll", await ((IQueryable<Organization>)_context.Organizations).ToPagedListAsync(1, 10)) });
            }
            else
            {
                var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));
            }

            item.Parents.Add(new Organization());
            return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEdit", item) });
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            await _context.Organizations
                .Where(x => x.ParentId == id)
                .ForEachAsync(x => x.ParentId = null); // Parent Ids auf null sezten

            var item = await _context.Organizations.FindAsync(id);
            _context.Organizations.Remove(item);

            await _context.SaveChangesAsync();

            return Json(new { html = Helper.RenderRazorViewToString(this, "_ViewAll", await ((IQueryable<Organization>)_context.Organizations).ToPagedListAsync(1, 10)) });
        }


        //[HttpPost]
        //public IActionResult Index(string selectedItems)
        //{
        //    if (selectedItems != null)
        //    {
        //        List<TreeViewNode> items = JsonConvert.DeserializeObject<List<TreeViewNode>>(selectedItems);
        //    }

        //    return RedirectToAction("Index", "Organization");
        //}

        public async Task UpdateFullShortName(List<Organization> organizations)
        {
            foreach (var organization in organizations)
            {
                foreach (var item in organizations)
                {
                    item.FullShortName = GetFullShortName(organizations, item.ParentId, item.ShortName);
                    _context.Update(item);
                }
            }
            await _context.SaveChangesAsync();
        }

        private string GetFullShortName(List<Organization> items, int? parentId, string? name)
        {
            foreach (var item in items)
            {
                if (item.Id == parentId)
                {
                    if (item.ParentId.HasValue)
                    {
                        return GetFullShortName(items, item.ParentId.Value, item.ShortName + " " + name);
                    }
                    else
                    {
                        return item.ShortName + name + " ";
                    }
                }
            }

            return name;
        }
    }
}