using EDPlayerJournal.Entries;

namespace EDPlayerJournal.BGS.Parsers;

internal class RedeemVoucherParser : ITransactionParserPart {
    public void Parse(Entry e, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
        RedeemVoucherEntry? entry = e as RedeemVoucherEntry;
        if (entry == null) {
            throw new NotImplementedException();
        }

        if (context.CurrentSystem == null) {
            transactions.AddIncomplete(new Vouchers(),
                "Could not find out where the vouchers were redeemed", e
                );
            return;
        }

        List<Faction>? current_factions = context.GetFactions(context.CurrentSystem);
        if (current_factions == null) {
            transactions.AddIncomplete(new Vouchers(),
                "Current system factions are unknown, so vouchers were ineffective", e);
        }

        foreach (string faction in entry.Factions) {
            bool relevantBond = false;
            string relevantFaction = faction;

            if (string.Compare(faction, Factions.PilotsFederationVouchers) == 0) {
                // Target faction is pilots' federation, so we assume thargoid bonks
                // Also assign this combat bond to the Pilots Federation
                relevantFaction = Factions.PilotsFederation;
                relevantBond = true;
            }

            if (current_factions != null && !relevantBond) {
                // If we have local factions, and it ain't thargoid bonds see if the bonds were
                // useful in the current system
                if (current_factions.Find(x => string.Compare(x.Name, faction, true) == 0) != null) {
                    relevantBond = true;
                } else {
                    transactions.AddIncomplete(new Vouchers(),
                        string.Format("Vouchers for \"{0}\" had no effect in \"{1}\" since said " +
                        "faction is not present there", faction, context.CurrentSystem), e
                    );
                }
            }

            if (!relevantBond) {
                continue;
            }

            var voucher = new Vouchers(entry) {
                System = context.CurrentSystem,
                Station = context.CurrentStation,
                Faction = relevantFaction,
                ControllingFaction = context.ControllingFaction,
                IsLegacy = context.IsLegacy,
            };

            if (options.FilterDoubleRedeemVouchers) {
                // To filter out doubly redeemed vouchers, find another redeem voucher
                // event that happened in the same system, same total sum, and also the
                // same faction. If there is one, filter this one out.
                var doubledEntry = transactions
                    .OfType<Vouchers>()
                    .Where(x => x.TotalSum == voucher.TotalSum &&
                                x.System == voucher.System &&
                                x.Faction == voucher.Faction)
                    .ToList()
                    ;
                if (doubledEntry.Count > 0) {
                    transactions.AddIncomplete(
                        voucher, 
                        string.Format("A doubled redeem voucher for {0} valued {1} was detected",
                                      voucher.Faction, Credits.FormatMillions(voucher.TotalSum)), 
                        e);
                    return;
                }
            }
            transactions.Add(voucher);
        }
    }
}