using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Antlr.Runtime.Misc;
using AutomatizovanySklad.Core.Entity;
using Web.Models.Karta;
using System.Data.Entity.Migrations;
using Web.Models.Karta.Produkt;
using Web.Models.Subjekt;
using System.Web;

namespace Web.Controllers {
  [Authorize(Roles = "Vedouci,Skladnici")]
  public class KartaController : BaseController {

    public ActionResult Index() {
      var listSkladovychKaret = databaze.Karty.Where(k => k.JeAktivni).ToList();
      var listSkladovychKaretModel = new KartaListModel();
      listSkladovychKaret.ForEach(l => listSkladovychKaretModel.Karty.Add(EntitaToKarta(l)));
      listSkladovychKaretModel.Title = "Seznam skladových karet";
      return View(listSkladovychKaretModel);
    }

    [Authorize(Roles = "Vedouci")]
    public ActionResult Vytvor() {
      var kartaModel = new KartaModel();
      kartaModel.SeznamProduktu = new List<ProduktModel>();
      kartaModel.SeznamSubjektu = new ListStack<SubjektModel>();
      kartaModel.Title = "Vytvoření skladové karty";
      return View(kartaModel);
    }

    [HttpPost]
    public ActionResult Vytvor(KartaModel kartaModel) {
      if (ModelState.IsValid) {
        var karta = KartaToEntita(kartaModel);
        karta = PridejDatumVytvoreni(karta);
        karta.JeAktivni = true;
        databaze.Karty.Add(karta);
        databaze.SaveChanges();
        Success("Karta byla úspěšně vytvořena.", true);
      }
      return RedirectToAction("Index", "Karta");
    }

    [Authorize(Roles = "Vedouci")]
    public ActionResult Editovat(int id) {
      var karta = databaze.Karty.First(k => k.Id == id);
      var kartaModel = EntitaToKartaEdit(karta);
      kartaModel.Title = "Editace skladové karty";
      return View(kartaModel);
    }

    [HttpPost]
    public ActionResult Editovat(KartaEditModel kartaModel) {
      if (ModelState.IsValid) {
        var karta = KartaEditToEntita(kartaModel);
        karta = PridejDatumZmeny(karta);
        //nebo nastavit hidden jeAktivni
        karta.JeAktivni = true;
        databaze.Karty.AddOrUpdate(karta);
        databaze.SaveChanges();
        Success("Karta byla úspěšně editována.", true);
      }
      return RedirectToAction("Index", "Karta");
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult VytvorProdukt(int id) {
      //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.KartaId = databaze.Karty.First(z => z.Id == id).Id;
      produktModel.Title = "Přidej produkt";
      return View("~/Views/Karta/Produkt/Pridej.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 VytvorProdukt(ProduktModel produktModel, HttpPostedFileBase upload) {
      if (ModelState.IsValid) {
        var karta = databaze.Karty.First(z => z.Id == produktModel.Id);
        var produkt = ProduktToEntita(produktModel);
        PridejDatumVytvoreni(produkt);
        if (!JeKorektniPridavaniProduktu(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);

        if (upload != null && upload.ContentLength > 0) {
          var soubor = new Soubor {
            NazevSouboru = System.IO.Path.GetFileName(upload.FileName),
            TypSouboru = upload.ContentType
          };
          using (var reader = new System.IO.BinaryReader(upload.InputStream)) {
            soubor.Obsah = reader.ReadBytes(upload.ContentLength);
          }
          produkt.Soubor = soubor;
        }
        karta.SeznamProduktu.Add(produkt);
        karta.JeAktivni = true;
        databaze.Karty.AddOrUpdate(karta);
        databaze.SaveChanges();
        Success("Produkt byl úspěšně vytvořen.", true);
      }
      return RedirectToAction("Detail", "Karta", new { id = produktModel.KartaId });
    }


    [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/Karta/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);
        //PridejDatumVytvoreni(produkt);

        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 });
    }

    [Authorize(Roles = "Skladnici")]
    public ActionResult SmazatProdukt(int idKarty, int idProduktu) {
      var produkt = databaze.Produkty.FirstOrDefault(z => z.Id == idProduktu);
      databaze.Produkty.Remove(produkt);
      databaze.SaveChanges();
      Success("Produkt byl úspěšně smazán.", true);
      return RedirectToAction("Detail", "Karta", new { id = idKarty });
    }

    [Authorize(Roles = "Vedouci")]
    public ActionResult Smazat(int id) {
      var karta = databaze.Karty.FirstOrDefault(z => z.Id == id);
      karta.JeAktivni = false;
      databaze.Karty.AddOrUpdate(karta);
      databaze.SaveChanges();
      Success("Karta byla úspěšně smazána.", true);
      return RedirectToAction("Index", "Karta");
    }

    public ActionResult Detail(int id) {
      var kartaModel = EntitaToKarta(databaze.Karty.First(z => z.Id == id));
      kartaModel.Title = "Detail skladové karty";
      return View(kartaModel);
    }

    public ActionResult Stahnout(int idKarty, int idProduktu) {
      var produkt = databaze.Produkty.FirstOrDefault(z => z.Id == idProduktu);
      Success("Stahování.", true);
      if (produkt != null) { return File(produkt.Soubor.Obsah, produkt.Soubor.TypSouboru); } else {
        Danger("Cyhba u stahování souboru.", true);
        return RedirectToAction("Detail", "Karta", new { id = idKarty });
      }
    }

    public ActionResult Objednat() {
      //Vybíra se karta z které vybíráme, vytvoříme BO nahrajeme uzivatele a jeho email
      var kartaObjednatModel = new KartaObjednatModel();
      kartaObjednatModel.UzivatelId = _userManager.FindByNameAsync(User.Identity.Name).Result.Id;
      //Nahrajeme seznam všech subjektu které mají email. Předěláme na List subjektů a znovu přidáme do modelu.
      var seznamSubjektu = databaze.Subjekty.Include(nameof(Adresa)).Include(nameof(Kontakt)).Where(s => !String.IsNullOrEmpty(s.Kontakt.Email));
      var seznamSubjektuSEmailem = new List<SubjektModel>();
      foreach (var subjekt in seznamSubjektu) {
        seznamSubjektuSEmailem.Add(EntitaToSubjekt(subjekt));
      }
      //Nahrajeme SelectItemy
      kartaObjednatModel.VybranaKarta = databaze.Karty.Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Nazev });
      kartaObjednatModel.VybranySubjekt = seznamSubjektuSEmailem.Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.Jmeno + " - " + x.Kontakt.Email });
      kartaObjednatModel.Title = "Vytvoření objednávky";
      return View(kartaObjednatModel);
    }

    [HttpPost]
    public ActionResult Objednat(KartaObjednatModel kartaObjednatModel, HttpPostedFileBase fileUploader) {
      if (ModelState.IsValid) {
        var emailDoruceni = databaze.Subjekty.Include(nameof(Kontakt)).First(z => z.Id == kartaObjednatModel.VybranySubjektId).Kontakt.Email;
        OdesliEmail(kartaObjednatModel.Text, "dobesstavbysro@seznam.cz", "Dobeš stavby s.r.o.", emailDoruceni, "Objednávka", "Heslo123*", fileUploader);
        Success("Email byl úspěšně odeslán.", true);
        return RedirectToAction("Index", "Karta");
      }
      Danger("Něco se nepovedlo, Email se nepovedlo odeslat.", true);
      return RedirectToAction("Index", "Karta");
    }

    public JsonResult ExistujeKartaEditace(string nazev, int id) {
      return Json(!databaze.Karty.Where(x => x.JeAktivni).Where(x => x.Id != id).Any(x => x.Nazev == nazev), JsonRequestBehavior.AllowGet);
    }

    public JsonResult ExistujeKartaVytvoreni(string nazev) {
      return Json(!databaze.Karty.Where(x => x.JeAktivni).Any(x => x.Nazev == nazev), JsonRequestBehavior.AllowGet);
    }
  }
}