using FluentValidation;
using System;
using System.Data;
using WK5.Core.Models;
using WK5.Core.PageModels.Stammdaten.Artikeldaten;
using KarleyLibrary.Erweiterungen;
using System.Linq;

namespace WK5.Core.Validators.Stammdaten.Artikeldaten
{
    public class ArtikelValidator : AbstractValidator<Artikel>
    {
        public ArtikelValidator(IValidator<StaffelpreisCollection> staffelValidator, IValidator<ArtikelAngebot> angebotValidator)
        {
            RuleFor(arti => arti.ARTI_L_INAKTIV)
                .Must((arti, inaktiv) => inaktiv ? arti.Bestand <= 0 : true)
                .WithMessage("Der Artikel kann nicht inaktiv gestellt werden wenn ein Bestand vorhanden ist!");

            RuleFor(arti => arti.WK5_ARTI_A_HINWEIS)                
                .ISO88591();


            RuleFor(arti => arti.Artikelnummer)
                .MaximumLength(30)
                .NotEmpty()
                .ISO88591()
                .Must((nr) =>
                {
                    return String.IsNullOrWhiteSpace(nr) ? true : System.Text.RegularExpressions.Regex.IsMatch(nr, "^[a-zA-Z0-9äÄöÖüÜ_-]*$");
                })
                .WithMessage("'{PropertyName}' darf nur '-', '_' und Alphanumerische Zeichen enthalten.");

            RuleFor(arti => arti.Lagerplatz)
                .ISO88591()
                .MaximumLength(20);

            RuleFor(arti => arti.Bezeichnung1)
                .ISO88591()
                .MaximumLength(60)
                .NotEmpty();

            RuleFor(arti => arti.Bezeichnung2)
                .ISO88591()
                .MaximumLength(60);

            RuleFor(arti => arti.Bezeichnung3)
                .ISO88591()
                .MaximumLength(60);

            RuleFor(arti => arti.Bezeichnung4)
                .ISO88591()
                .MaximumLength(60);

            RuleFor(arti => arti.Bezeichnung5)
                .ISO88591()
                .MaximumLength(60);

            RuleFor(arti => arti.ARTI_A_EINHEIT)
                .MaximumLength(5);

            RuleFor(arti => arti.Warengruppe)
                .MaximumLength(10);

            RuleFor(arti => arti.Unterwarengruppe)
                .MaximumLength(10);

            RuleFor(arti => arti.Preisgruppe)
                .MaximumLength(10)
                .WithName("Preisgruppe");

            RuleFor(arti => arti.ARTI_N_VK1)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_VK2)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_VK3)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_VK4)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_VK5)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_MWSTKENNUNG)
                .GreaterThanOrEqualTo(1)
                .WithName("Mehrwersteuer Schlüssel");

            RuleFor(arti => arti.ARTI_N_MINDAUFSCHL)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_MIND_VK)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_MAXRABATT)
                .InclusiveBetween(0, 100);

            RuleFor(arti => arti.ARTI_N_GEWICHT)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.Breite)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_HOEHE)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_LAENGE)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_BREITE_VERPACKUNG)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_LAENGE_VERPACKUNG)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_HOEHE_VERPACKUNG)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_COLLI)
                .GreaterThanOrEqualTo(1);

            RuleFor(arti => arti.Mindestbestand)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.ARTI_N_MAXBESTAND)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.Hersteller)
                .MaximumLength(20);

            RuleFor(arti => arti.Herstellernummer)
                .MaximumLength(30);

            RuleFor(arti => arti.ARTI_A_EAN)
                .MaximumLength(13);

            RuleFor(arti => arti.ARTI_A_URSPRUNGSLAND)
                .MaximumLength(3);

            RuleFor(arti => arti.ARTI_A_ERSATZART)
                .MaximumLength(30);

            RuleFor(arti => arti.Selektionsmerkmal1)
                .MaximumLength(10);

            RuleFor(arti => arti.Selektionsmerkmal2)
                .MaximumLength(10);

            RuleFor(arti => arti.Selektionsmerkmal3)
                .MaximumLength(10);

            RuleFor(arti => arti.Staffelpreise)
                .SetValidator(staffelValidator);

            RuleForEach(arti => arti.Sonderangebote)
                .SetValidator(angebotValidator);

           

           
            
            RuleFor(arti => arti.WK5_ARTI_N_PRODUKTGEWICHT)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_MUELL_PLASTIK)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_MUELL_VERBUNDSTOFF)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_MUELL_PAPIER)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_MUELL_ALUMINIUM)
                .GreaterThanOrEqualTo(0);

            RuleFor(arti => arti.WK5_ARTI_N_VIRT_LAGER)
                .Must((arti, x) => x <= 0 ? true : x % arti.ARTI_N_COLLI == 0)
                .WithMessage("{PropertyName} muss ein vielfaches der Mindestabnahme sein");

            RuleFor(x => x.ARTI_N_EK)
                .GreaterThan(0)
                .When(x => !x.ARTI_L_DIENSTLEIST && !x.ARTI_L_INAKTIV);

            RuleFor(x => x.WartungsText)
                .NotEmpty()
                .NotNull()
                .WithMessage("Es muss ein Text für die Wartungsemail angegeben werden, wenn ein Wartungsintervall hinterlegt ist.")
                .When(x => x.Wartungsintervall > 0);

            RuleFor(x => x.Wartungsintervall)
                .LessThanOrEqualTo(24)
                .GreaterThanOrEqualTo(0);
            
        }
    }
}
