using Elwig.Helpers;
using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using System.Collections.Generic;
using System.Linq;

namespace Elwig.Documents {
    public class CreditNote : BusinessDocument {

        public new static string Name => "Traubengutschrift";

        public PaymentMember? Payment;
        public Credit? Credit;
        public CreditNoteData Data;
        public string? Text;
        public string CurrencySymbol;
        public int Precision;
        public string MemberModifier;
        public IEnumerable<(string Name, int Kg, decimal Amount)>? MemberUnderDeliveries;
        public decimal MemberTotalUnderDelivery;
        public decimal MemberAutoBusinessShares;

        public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteData data, Dictionary<string, UnderDelivery>? underDeliveries = null) :
            base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
            UseBillingAddress = true;
            ShowDateAndLocation = true;
            Data = data;
            Payment = p;
            Credit = p.Credit;
            var season = p.Variant.Season;
            var mod = App.Client.IsMatzen ? ctx.Modifiers.Where(m => m.Year == season.Year && m.Name.StartsWith("Treue")).FirstOrDefault() : null;
            if (mod != null) {
                MemberModifier = $"{mod.Name} ({mod.ValueStr})";
            } else {
                MemberModifier = "Sonstige Zu-/Abschläge";
            }
            var total = data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
            var totalUnderDelivery = total - p.Member.BusinessShares * season.MinKgPerBusinessShare;
            MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) : 0;
            var fromDate = $"{season.Year}-06-01";
            var toDate = $"{season.Year + 1}-06-01";
            MemberAutoBusinessShares = ctx.MemberHistory
                .Where(h => h.MgNr == p.Member.MgNr && h.Type == "auto")
                .Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) < 0)
                .Sum(h => h.BusinessShares) * (-season.BusinessShareValue ?? 0);
            if (total == 0) MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0);
            Aside = Aside.Replace("</table>", "") +
                $"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
                $"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : "-")}</td></tr>" +
                $"<tr><th>Überw. am</th><td>{p.Variant.TransferDate:dd.MM.yyyy}</td></tr>" +
                $"<tr><th>Datum/Zeit</th><td>{p.Credit?.ModifiedTimestamp:dd.MM.yyyy} / {p.Credit?.ModifiedTimestamp:HH:mm}</td></tr>" +
                $"</tbody></table>";
            Text = App.Client.TextDeliveryNote;
            DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : p.MgNr);
            CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
            Precision = season.Precision;

            var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
            var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
            var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
            MemberUnderDeliveries = underDeliveries?
                .OrderBy(u => u.Key)
                .Select(u => (
                    varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
                    u.Value.Diff,
                    u.Value.Diff * (comTypes[u.Key].PenaltyPerKg ?? 0)
                      - (comTypes[u.Key].PenaltyAmount ?? 0)
                      - ((u.Value.Weight == 0 ? comTypes[u.Key].PenaltyNone : null) ?? 0)))
                .Where(u => u.Item3 != 0)
                .ToList();
        }
    }}