using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using AutomatizovanySklad.Core.Entity;
using Web.Models.DodaciList;
using Web.Models.Karta.Produkt;
using WebGrease.Css.Extensions;

namespace Web.Controllers {
  [Authorize(Roles = "Vedouci,Skladnici")]
  public class DodaciListController : BaseController {
    public ActionResult Index() {
      var model = new DodaciListListModel();
      var dodaciListy = databaze.DodaciListy.Where(d => d.JeAktivni).Include(nameof(Subjekt));
      dodaciListy.ForEach(l => model.DodaciListy.Add(EntitaToDodaciList(l)));
      model.Title = "Seznam dodacích listů";
      return View(model);
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult Vytvor() {
      var dodaciListModel = new DodaciListModel();
      dodaciListModel.Title = "Vytvoření dodacího listu";
      dodaciListModel.Zaznamy.Add(new DodaciListZaznamModel {
        VybranaKarta = databaze.Karty.Where(k => k.JeAktivni).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Nazev })
      });
      dodaciListModel.VybranySubjekt = databaze.Subjekty.Where(s => s.JeAktivni).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Jmeno });
      return View(dodaciListModel);
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult Editovat(int id) {
      var dodaciList = databaze.DodaciListy.First(k => k.Id == id);
      var dodaciListModel = EntitaToDodaciListEdit(dodaciList);
      dodaciListModel.VybranySubjekt = databaze.Subjekty.Where(s => s.JeAktivni).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Jmeno });

      dodaciListModel.VybranySubjektId = dodaciList.Subjekt.Id;
      dodaciListModel.Title = "Editace dodacího listu";
      //Pridej produktu karta ID
      dodaciListModel.Zaznamy.ForEach(z => {
        databaze.Karty.ForEach(k => {
          if (k.SeznamProduktu.Any(p => p.Id == z.ProduktModel.Id)) {
            z.ProduktModel.KartaId = k.Id;
          };
        });
        //pokud produkt model ma kartu ID tak se vypise nazev
        if (z.ProduktModel.KartaId != 0) z.ProduktModel.KartaNazev = databaze.Karty.FirstOrDefault(k => k.Id == z.ProduktModel.KartaId).Nazev;
      });
      return View(dodaciListModel);
    }

    [HttpPost]
    public ActionResult Editovat(DodaciListEditModel dodaciListModel) {
      if (ModelState.IsValid) {
        //Nastavení pravdy na true, pokud ve foreachu spadne nastavi se na false
        var pravda = true;
        var vyberDodaciListZDatabaze = databaze.DodaciListy.First(k => k.Id == dodaciListModel.Id);
        var prevedDodaciListZaznamy = EntitaToDodaciListEdit(vyberDodaciListZDatabaze);
        //Prvně zkontroluji zda je korektni pridavani 
        var listProdkutu = new List<Produkt>();
        //Prevedu list zaznamu ten neupravujeme 
        dodaciListModel.Zaznamy = prevedDodaciListZaznamy.Zaznamy;
        //Každemu zaznamu najdi kartaId pro pozdeji posilani karty
        dodaciListModel.Zaznamy.ForEach(z => {
          databaze.Karty.ForEach(k => {
            if (k.SeznamProduktu.Any(p => p.Id == z.ProduktModel.Id)) {
              z.ProduktModel.KartaId = k.Id;
            };
          });
        });

        dodaciListModel.Zaznamy.ForEach(l => {
          var karta = databaze.Karty.First(z => z.Id == l.ProduktModel.KartaId);
          var produkt = ProduktToEntita(l.ProduktModel);
          if (dodaciListModel.TypTransakce == TypTransakce.Prodej) {
            produkt.TypTransakce = TypTransakce.Prodej;
          } else {
            produkt.TypTransakce = TypTransakce.Nákup;
          }
          //Kontrola zda je typtransakce změněna
          var kontrolaTransakceProduktu = databaze.Produkty.FirstOrDefault(p => p.Id == produkt.Id).TypTransakce;
          //Pokud je změněna zkontroluj počet
          if (produkt.TypTransakce != kontrolaTransakceProduktu) {
            if (!JeKorektniEditovaniProduktu(produkt, karta)) {
              pravda = false;
            }
          }
          //Pokud je korektni muzeme pokracovat
          if (pravda) {
            listProdkutu.Add(produkt);
            databaze.Produkty.AddOrUpdate(produkt);
            ZkontrolujStavZboziAUpozorni(karta);
          }
        });
        if (!pravda) {
          Danger("Produkt není na skladě nebo byl přesáhnut maximální skladový prostor. Nebylo jej tedy možné uložit!", true);
          return RedirectToAction("Detail", "DodaciList", new { id = dodaciListModel.Id });
        }
        var dodaciList = DodaciListEditToEntita(dodaciListModel);
        //Pridani subjektu 
        //dodaciList.Subjekt = databaze.Subjekty.FirstOrDefault(s => s.Id == dodaciListModel.VybranySubjektId);
        dodaciList.Subjekt = vyberDodaciListZDatabaze.Subjekt;
        dodaciList.SeznamProduktu = vyberDodaciListZDatabaze.SeznamProduktu;
        dodaciList = PridejDatumZmeny(dodaciList);
        dodaciList.JeAktivni = true;
        databaze.DodaciListy.AddOrUpdate(dodaciList);
        databaze.SaveChanges();
        Success("Dodací list byl úspěšně editován.", true);
      }
      return RedirectToAction("Index", "DodaciList");
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult Smazat(int id) {
      var dodaciList = databaze.DodaciListy.FirstOrDefault(z => z.Id == id);
      var jeOdebraniKorektni = true;
      //Smazani jednotlivych produktu
      var dodaciListModel = EntitaToDodaciListEdit(dodaciList);
      var karta = new Karta();
      dodaciList.SeznamProduktu.ForEach(p => {
        databaze.Karty.ForEach(k => {
          var jeToKartaProduktu = k.SeznamProduktu.Any(s => s.Id == p.Id);
          if (jeToKartaProduktu) {
            karta = k;
          }
        });
        if (!JeKorektniOdebiraniProduktu(p, karta)) {
          jeOdebraniKorektni = false;
        }
      });

      if (!jeOdebraniKorektni) {
        Warning("Nemůžeš smazat dodací list, sklad nemůže jít do mínusu nebo přes maximum! ");
        return RedirectToAction("Index", "DodaciList");
      }

      var seznamProduktu = new List<Produkt>();
      dodaciList.SeznamProduktu.ForEach(p => seznamProduktu.Add(p));


      foreach (var produkt in seznamProduktu) {
        databaze.Produkty.Remove(produkt);
      }

      dodaciList.JeAktivni = false;
      databaze.DodaciListy.AddOrUpdate(dodaciList);
      databaze.SaveChanges();
      Success("Dodací list byl úspěšně smazán.", true);
      return RedirectToAction("Index", "DodaciList");
    }

    [HttpPost]
    public ActionResult UlozDodaciList(DodaciListModel model) {
      if (ModelState.IsValid & model.Zaznamy.Count > 0) {
        if (!databaze.DodaciListy.Any(x => x.KodDodacihoListu == model.KodDodacihoListu)) { 
        var jePridaniKorektni = true;
          model.KodDodacihoListu = model.KodDodacihoListu.ToLower();
        //Nový dodaci list
        var dodaciList = DodaciListToEntita(model);
        dodaciList = PridejDatumVytvoreni(dodaciList);
        //Pridani jednotlivých produktů do karet v databazi
        model.Zaznamy.ForEach(z => {
          var karta = databaze.Karty.First(k => k.Id == z.VybranaKartaId);
          var produkt = ProduktToEntita(z.ProduktModel);
          produkt = PridejDatumVytvoreni(produkt);
          if (JeKorektniPridavaniProduktu(produkt, karta, model.TypTransakce)) {
            ZkontrolujStavZboziAUpozorni(karta);
            karta.SeznamProduktu.Add(produkt);
            dodaciList.SeznamProduktu.Add(produkt);
            databaze.Karty.AddOrUpdate(karta);
          } else { jePridaniKorektni = false; }
        });
        if (jePridaniKorektni) {
          dodaciList.JeAktivni = true;
          databaze.DodaciListy.Add(dodaciList);
          databaze.SaveChanges();
          Success("Vytváření Příjemky / Výdejky uloženo!", true);
          return Json(new { url = Url.Action("Detail", "DodaciList", new { id = dodaciList.Id }), zprava = "provedeno" });
        }
        return Json(new { url = Url.Action("Vytvor", "DodaciList"), zprava = "nedostatek", model });
      }
        return Json(new { url = Url.Action("Vytvor", "DodaciList"), zprava = "neplatnyNazev", model });
      }
      return Json(new { url = Url.Action("Vytvor", "DodaciList"), zprava = "chyba", model });

    }

    public ActionResult Detail(int id) {
      var dodaciList = databaze.DodaciListy.First(k => k.Id == id);
      var dodaciListModel = EntitaToDodaciListEdit(dodaciList);
      dodaciListModel.VybranySubjekt = databaze.Subjekty.Where(s => s.JeAktivni).Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Jmeno });

      dodaciListModel.VybranySubjektId = dodaciList.Subjekt.Id;
      dodaciListModel.Title = "Editace dodacího listu";
      //Pridej produktu karta ID
      dodaciListModel.Zaznamy.ForEach(z => {
        databaze.Karty.ForEach(k => {
          if (k.SeznamProduktu.Any(p => p.Id == z.ProduktModel.Id)) {
            z.ProduktModel.KartaId = k.Id;
          };
        });
        //pokud produkt model ma kartu ID tak se vypise nazev
        if (z.ProduktModel.KartaId != 0) z.ProduktModel.KartaNazev = databaze.Karty.FirstOrDefault(k => k.Id == z.ProduktModel.KartaId).Nazev;
      });
      return View(dodaciListModel);
    }


    public ActionResult SaveUploadedFile() {
      bool isSavedSuccessfully = true;
      string fName = "";
      try {
        //Z dotazu vytáhnu idDodaciKarty
        var dotaz = Request.UrlReferrer.Query;
        var findIndexId = dotaz.IndexOf("=");
        var pocet = (dotaz.Length - 1) - findIndexId;
        var substring = dotaz.Substring(findIndexId + 1, pocet);
        int dodaciListId;
        //pokud dostanu číslo 
        var pravda = int.TryParse(substring, out dodaciListId);

        if (pravda) {
          //dodaciListId.
          foreach (string fileName in Request.Files) {
            HttpPostedFileBase file = Request.Files[fileName];
            //Save file content goes here
            fName = file.FileName;
            if (file != null && file.ContentLength > 0) {
              if (file != null && file.ContentLength > 0) {
                var soubor = new Soubor {
                  NazevSouboru = System.IO.Path.GetFileName(file.FileName),
                  TypSouboru = file.ContentType
                };
                using (var reader = new System.IO.BinaryReader(file.InputStream)) {
                  soubor.Obsah = reader.ReadBytes(file.ContentLength);
                }
                var dodaciList = databaze.DodaciListy.First(d => d.Id == dodaciListId);
                dodaciList.Soubory.Add(soubor);
                databaze.SaveChanges();
              }

            }
          }
        }
      } catch (Exception ex) {
        var zprava = ex.ToString();
        isSavedSuccessfully = false;
      }
      if (isSavedSuccessfully) {
        return Json(new { Message = fName });
      } else {
        return Json(new { Message = "Error in saving file" });
      }
    }

    //Načtení dropzone
    public ActionResult PridatFaktury(int idListu) {
      var dodaciList = EntitaToDodaciList(databaze.DodaciListy.First(d => d.Id == idListu));
      return View("Dropzone", dodaciList);
    }

    //Volani v dropzone jedna po druhe 
    public ActionResult NactiFaktury(int id) {
      var dodaciList = EntitaToDodaciList(databaze.DodaciListy.First(d => d.Id == id));
      var soubory = dodaciList.Soubory;

      var serializer = new JavaScriptSerializer();

      //Pro velké soubory, defaultně ASP NET 4 Mb
      serializer.MaxJsonLength = Int32.MaxValue;

      var result = new ContentResult {
        Content = serializer.Serialize(soubory),
        ContentType = "application/json"
      };
      return result;
    }

    public ActionResult StahnoutFakturu(int id) {
      var faktura = databaze.Soubory.First(s => s.Id == id);
      return File(faktura.Obsah, faktura.TypSouboru, faktura.NazevSouboru);
    }

    public ActionResult VymazatFakturu(int id) {
      //Z dotazu vytáhnu idDodaciKarty
      var dotaz = Request.UrlReferrer.Query;
      var findIndexId = dotaz.IndexOf("=");
      var pocet = (dotaz.Length - 1) - findIndexId;
      var substring = dotaz.Substring(findIndexId + 1, pocet);
      int dodaciListId;
      //pokud dostanu číslo 
      var pravda = int.TryParse(substring, out dodaciListId);

      if (pravda) {

        var faktura = databaze.Soubory.First(s => s.Id == id);
        databaze.Soubory.Remove(faktura);
        databaze.SaveChanges();
      }
      return RedirectToAction("PridatFaktury", new { idListu = dodaciListId });

    }

    public JsonResult ExistujeDodaciListEditace(string kodDodacihoListu, int id) {
      return Json(!databaze.DodaciListy.Where(x => x.Id != id).Any(x => x.KodDodacihoListu == kodDodacihoListu), JsonRequestBehavior.AllowGet);
    }

    public JsonResult ExistujeDodaciListVytvor(string kodDodacihoListu) {
      var pravda = !databaze.DodaciListy.Any(x => x.KodDodacihoListu == kodDodacihoListu);
      return Json(!databaze.DodaciListy.Any(x => x.KodDodacihoListu == kodDodacihoListu), JsonRequestBehavior.AllowGet);
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult EditovatProdukt(int idKarty, int idProduktu) {
      //Potřeba vytahnout kartu do ní přidat nový produkt, následně vytáhnout ten poslední a pracovat s ním
      var produktModel = new ProduktModel();
      produktModel = EntitaToProdukt(databaze.Produkty.First(z => z.Id == idProduktu));
      produktModel.KartaId = idKarty;
      produktModel.Title = "Přidej produkt";
      return View("~/Views/DodaciList/Produkt/Editovat.cshtml", produktModel);
    }

    //Přidej produkt, z view přijde model, kontrola zda je validní.
    //Následně vybere kartu do které produkt vložit a kontrola zda jde o příjem nebo vydej
    [HttpPost]
    public ActionResult EditovatProdukt(ProduktModel produktModel) {
      if (ModelState.IsValid) {
        var karta = databaze.Karty.First(z => z.Id == produktModel.KartaId);

        var produkt = ProduktToEntita(produktModel);
        //Kontrola zda je typtransakce změněna
        var kontrolaTransakceProduktu = databaze.Produkty.FirstOrDefault(p => p.Id == produkt.Id).TypTransakce;
        //Pokud je změněna zkontroluj počet
        if (produkt.TypTransakce != kontrolaTransakceProduktu) {
          if (!JeKorektniEditovaniProduktu(produkt, karta)) {
            Danger("Produkt není na skladě nebo byl přesáhnut maximální skladový prostor. Nebylo jej tedy možné uložit!", true);
            return RedirectToAction("Detail", "Karta", new { id = produktModel.KartaId });
          }
        }
        ZkontrolujStavZboziAUpozorni(karta);
        produkt = PridejDatumZmeny(produkt);
        databaze.Produkty.AddOrUpdate(produkt);
        databaze.SaveChanges();
        Success("Produkt byl úspěšně editován.", true);
      }
      return RedirectToAction("Detail", "Karta", new { id = produktModel.KartaId });
    }
  }
}