using System.Net;
using System.Web.Mvc;
using CD67.FicheCollege.Entity;
using CD67.FicheCollege.Factory;
using CD67.FicheCollege.MVC.Models;
using System.Linq;
using System.Collections.Generic;
using System;

namespace CD67.FicheCollege.MVC.Controllers
{
    public class CollegesController : Controller
    {
        private Entities db = new Entities();

        // GET: Colleges
        public ActionResult Index(int? annee_id)
        {
            if (annee_id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            AnneeFactory fact = new AnneeFactory(db);
            Annee annee = fact.getById(annee_id);
            AnneeViewModel model = new AnneeViewModel(annee, db, ModeAcces.Lecture);
            return View(model);
        }

        // GET: Colleges/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            CollegeFactory collegeFactory = new CollegeFactory(db);
            Entity.College college = collegeFactory.getById(id);
            if (college == null)
            {
                return HttpNotFound();
            }

            college.hydrate();

            // Chargement des données Educ'facile
            if (!string.IsNullOrEmpty(college.CodeRne))
            {
                EducfEntities educfdb = new EducfEntities();
                EducfEtablissementFactory educfFact = new EducfEtablissementFactory(educfdb);
                etablissement educf_etablissement = educfFact.getByRne(college.CodeRne);
                if (educf_etablissement != null)
                {
                    try {
                        college.educfData.Add("Effectifs", educf_etablissement.etabeffectifannees.Where(e => e.annee == college.Annee.AnneeRentree).Sum(e => e.effectif).ToString());
                    } catch { college.educfData.Add("Effectifs", "(Données introuvables)"); }

                    try { 
                        college.educfData.Add("Effectif Bilingue", educf_etablissement.eleveannees.Where(e=>e.annee== college.Annee.AnneeRentree & e.idetablissement == 3 & e.idfiliere == 6).Count().ToString());
                    } catch { college.educfData.Add("Effectif Bilingue", "(Données introuvables)"); }

                    try { 
                        college.educfData.Add("Demi-pensionnaires", educf_etablissement.etablissementannees.Where(e=>e.annee== college.Annee.AnneeRentree).First().demipensionnaires.ToString());
                    } catch { college.educfData.Add("Demi-pensionnaires", "(Données introuvables)"); }

                    try { 
                    college.educfData.Add("Internes", educf_etablissement.etablissementannees.Where(e=>e.annee== college.Annee.AnneeRentree).First().capaciteeleves.ToString());
                    } catch { college.educfData.Add("Internes", "(Données introuvables)"); }

                    try { 
                        college.educfData.Add("Accessibilité handicapés", educf_etablissement.accueilhandicape != 0 ? "Oui" : "Non");
                    } catch { college.educfData.Add("Accessibilité handicapés", "(Données introuvables)"); }

                    try { 
                    college.educfData.Add("Capacité Théorique", educf_etablissement.etablissementannees.Where(e => e.annee == college.Annee.AnneeRentree).First().internes.ToString());
                    } catch { college.educfData.Add("Capacité Théorique", "(Données introuvables)"); }
                    try { 
                        List<string> liste_niveaux = new List<string>();
                        foreach(etabeffectifannee effectif in educf_etablissement.etabeffectifannees.Where(e => e.annee == college.Annee.AnneeRentree).OrderBy(e=>e.niveau.ordre))
                        {
                            liste_niveaux.Add(effectif.niveau.nom + ": " + effectif.effectif);
                        }
                        college.educfData.Add("Niveaux", string.Join(" - ", liste_niveaux));
                    } catch { college.educfData.Add("Niveaux", "(Données introuvables)"); }

                    try { 
                        List<string> liste_options = new List<string>();
                        foreach (etaboptionsannee opt in educf_etablissement.etaboptionsannees)
                        {
                            liste_options.Add(opt.matiereoption.nom);
                        }
                        college.educfData.Add("Options", string.Join(" - ", liste_options));
                    } catch { college.educfData.Add("Options", "(Données introuvables)"); }
                }
                else
                {
                    college.educfData.Add("Données Educ'Facile", "(Données introuvables)");
                }
            }
            
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Lecture);

            return View(model);
        }

        // GET: Colleges/Create
        public ActionResult Create(int? annee_id)
        {
            if (annee_id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Entity.College college = new Entity.College();
            college.Annee_Id = annee_id.Value;
            college.TokenId = Guid.NewGuid();

            AnneeFactory fact = new AnneeFactory(db);
            college.Annee = fact.getById(annee_id);
            college.hydrate();

            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Creation);

            return View("Edit", model);
        }

        // POST: Colleges/Create
        // Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour 
        // plus de détails, voir  http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Entity.College college)
        {
            if (ModelState.IsValid)
            {
                CollegeFactory collegeFactory = new CollegeFactory(db);
                collegeFactory.add(ref college);
                return RedirectToAction("Details", new { id = college.Id });
            }

            college.hydrate();
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Creation);

            return View("Edit", model);
        }

        // GET: Colleges/Edit/5
        public ActionResult Edit(int? id)
        {
            CollegeFactory collegeFactory = new CollegeFactory(db);
            Entity.College college = collegeFactory.getById(id);
            if (college == null)
            {
                return HttpNotFound();
            }
            college.hydrate();
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Modification);

            return View(model);
        }

        // POST: Colleges/Edit/5
        // Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour 
        // plus de détails, voir  http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Entity.College college)
        {
            if (ModelState.IsValid)
            {
                CollegeFactory collegeFactory = new CollegeFactory(db);
                collegeFactory.update(ref college);
                return RedirectToAction("Details", new { Id = college.Id });
            }
            college.hydrate();
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Modification);

            return View(model);
        }

        // GET: College/Type/5
        public ActionResult Type(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            CollegeFactory collegeFactory = new CollegeFactory(db);
            College col = collegeFactory.getById(id.Value);

            if (id == null)
            {
                return HttpNotFound();
            }
            col.hydrate();
            CollegeViewModel model = new CollegeViewModel(col, db, ModeAcces.Modification);

            return View(model);
        }

        // POST: College/Type/5
        // Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour 
        // plus de détails, voir  http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Type(Entity.College college)
        {
            if (ModelState.IsValid)
            {
                CollegeFactory collegeFactory = new CollegeFactory(db);
                collegeFactory.update(ref college);
                return RedirectToAction("Index", "Restauration", new { annee_id = college.Annee_Id });
            }
            college.hydrate();
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Modification);

            return View(model);
        }


        // GET: College/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            CollegeFactory collegeFactory = new CollegeFactory(db);
            Entity.College college = collegeFactory.getById(id);
            if (college == null)
            {
                return HttpNotFound();
            }
            college.hydrate();
            CollegeViewModel model = new CollegeViewModel(college, db, ModeAcces.Suppression);

            return View("Details", model);
        }

        // POST: College/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            CollegeFactory collegeFactory = new CollegeFactory(db);
            Entity.College college = collegeFactory.getById(id);
            int annee_id = college.Annee_Id;
            collegeFactory.delete(ref college);
            return RedirectToAction("Index", new { annee_id = annee_id });
        }

        public List<College> colleges_non_importes(int annee_id)
        {
            List<College> non_importes = new List<College>();
            AnneeFactory fact = new AnneeFactory(db);
            Annee annee_prec = fact.getById(annee_id - 1);

            foreach (College college in annee_prec.Colleges)
            {
                // Pour chaque college de l'année précédente, on vérifie s'il existe dans l'année en cours en se basant sur le TokenId
                if (!db.Colleges.Any(c=> c.TokenId == college.TokenId && c.Annee_Id == annee_id))
                {
                    non_importes.Add(college.flat());
                }
            }

            return non_importes;
        }

        // GET: Colleges
        public ActionResult Import(int? annee_id)
        {
            if (annee_id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            ImportCollegeViewModel model = new ImportCollegeViewModel();
            model.Annee_Id = annee_id.Value;
            model.set_liste(colleges_non_importes(annee_id.Value));

            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Import(int Annee_Id, List<int> colleges_ids, List<bool> selection)
        {
            CollegeFactory fact = new CollegeFactory(db);
            for (int i = 0; i < selection.Count; i++)
            {
                if (selection[i])
                {
                    int college_id = colleges_ids[i];
                    College college = fact.getById(college_id);
                    fact.clone_to_year(college, Annee_Id);
                }
            }
            return RedirectToAction("Index", new { annee_id = Annee_Id });
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
