using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using EliteBGS.LogGenerator;

namespace EliteBGS;

public class DiscordLogGenerator {
    protected List<LogFormatter> formatters = new List<LogFormatter>() {
        new MissionFormat(),
        new FailedMissionFormat(),
        new MurderFormat(),
        new VoucherFormat(),
        new ThargoidFormatter(),
        new CombatZoneFormat(),
        new KillBondsFormat(),
        new CartographicsFormat(),
        new MicroResourcesFormat(),
        new MarketBuyFormat(),
        new CargoSoldFormatter(),
        new VistaGenomicsFormat(),
        new SearchAndRescueFormat(),
    };

    protected virtual string GenerateSummary(Objective objective) {
        StringBuilder sb = new StringBuilder();

        foreach (var formatter in formatters) {
            string summary = "";

            try {
                summary = formatter.GenerateSummary(objective);
            } catch (NotImplementedException) {
            }

            if (string.IsNullOrEmpty(summary)) {
                continue;
            }

            if (sb.Length > 0) {
                sb.Append("; ");
            }

            sb.Append(summary);
        }

        return sb.ToString();
    }

    protected virtual string GenerateHeader() {
        return "";
    }

    protected virtual string GenerateFooter() {
        return "\n";
    }

    protected virtual string GenerateObjectiveHeader(Objective objective) {
        StringBuilder log = new StringBuilder();

        string location;

        if (!string.IsNullOrEmpty(objective.System) && !string.IsNullOrEmpty(objective.Faction)) {
            location = string.Format("{0}, {1}", objective.System, objective.Faction);
        } else if (!string.IsNullOrEmpty(objective.System)) {
            location = objective.System;
        } else {
            location = "Unknown Location";
        }

        int legacycount = objective.Transactions
                .Where(x => x.IsLegacy)
                .Count()
                ;

        string summary = GenerateSummary(objective);

        log.AppendFormat("**Date:** {0}\n", DateTime.Now.ToString("dd/MM/yyyy"));
        log.AppendFormat("**Target:** {0}\n", location);
        if (!string.IsNullOrEmpty(summary)) {
            log.AppendFormat("**Summary**: {0}\n", summary);
        }
        if (legacycount > 0) {
            log.AppendFormat("**Warning:** Some actions were performed on ED Legacy\n");
        }
        log.AppendLine("```");

        return log.ToString();
    }

    protected virtual string GenerateObjectiveFooter(Objective objective) {
        return "```\n";
    }

    /// <summary>
    /// Is called to do final adjustments to the log body of a given objective.
    /// </summary>
    /// <param name="objective">Objective in question.</param>
    /// <param name="log">Final log as generated.</param>
    /// <returns>The transformed log.</returns>
    protected virtual string TransformFinalLogForObjective(Objective objective, string log) {
        return log;
    }

    public virtual string GenerateDiscordLog(Report report) {
        StringBuilder log = new StringBuilder();

        if (report == null) {
            return "";
        }

        var objectives = report.Objectives
            .Where(x => x.IsEnabled && x.Transactions.Count() > 0)
            ;

        if (objectives == null || objectives.Count() <= 0) {
            return "";
        }

        log.AppendFormat("{0}", GenerateHeader());

        foreach (Objective objective in objectives) {
            StringBuilder objlog = new StringBuilder();

            log.AppendFormat("{0}", GenerateObjectiveHeader(objective));

            foreach (LogFormatter formatter in formatters) {
                string text = formatter.GenerateLog(objective);
                text = text.Trim();
                if (!string.IsNullOrEmpty(text)) {
                    objlog.AppendFormat("{0}\n\n", text);
                }
            }

            string finallog = objlog.ToString().Trim();
            finallog = TransformFinalLogForObjective(objective, finallog);

            log.AppendFormat("{0}\n", finallog);

            log.AppendFormat("{0}", GenerateObjectiveFooter(objective));
        }

        log.AppendFormat("{0}", GenerateFooter());

        return log.ToString().Trim();
    }
}
