using cadosys.HumanReadableRepresentation.Model;
using cadosys.HumanReadableRepresentation.Model.Labels;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using cadosys.HumanReadableRepresentation.Conversion;

namespace cadosys.HumanReadableRepresentation.HTML
{
    public class UnmappedField
    {
        public string Key { get; set; }
        public string Value { get; set; }

        public string PositionNumber { get; set; }

        public string Description { get; set; }
    }

    public class InvoiceHtmlGenerator
    {
        private string _currentState = File.ReadAllText("base_layout.html");
        private readonly string _lineItemTemplate = File.ReadAllText("line_item_layout.html");
        private readonly string _lineItemBlockTemplate = File.ReadAllText("position_layout.html");
        private readonly string _appendixTemplate = File.ReadAllText("appendix.html");
        private readonly string _appendixLineTemplate = File.ReadAllText("appendix_line_template.html");
        private HumanReadableRepresentationConfiguration _humanReadableRepresentationConfiguration = null;

        public InvoiceHtmlGenerator(HumanReadableRepresentationConfiguration humanReadableRepresentationConfiguration)
        {
            _humanReadableRepresentationConfiguration = humanReadableRepresentationConfiguration;
        }

        public void LoadDocumentLevelObject(object obj)
        {
            _currentState = PlaceholderProcessor.ReplacePlaceholders(_currentState, obj, _humanReadableRepresentationConfiguration);
        }

        public void LoadLineItemLevelObjects(IEnumerable<IGroupableInvoiceItem> objects)
        {
            var groups = objects.GroupBy(x => $"{x.OrderPositionNumber}{x.JobPositionNumber}");
            var blocks = new List<string>();

            foreach (var group in groups)
            {
                var lineItems = new List<string>();
                foreach (var item in group)
                {
                    lineItems.Add(PlaceholderProcessor.ReplacePlaceholders(_lineItemTemplate, item, _humanReadableRepresentationConfiguration));
                }

                var block = _lineItemBlockTemplate.Replace("{{LineItems}}", lineItems.Aggregate((a, b) => $"{a}{b}"));
                block = PlaceholderProcessor.ReplacePlaceholders(block, group.First(), _humanReadableRepresentationConfiguration);
                blocks.Add(block);
            }

            if (blocks.Count == 0)
            {
                _currentState = _currentState.Replace("{{LineItemBlock}}", string.Empty);
                return;
            }

            _currentState = _currentState.Replace("{{LineItemBlock}}", blocks.Aggregate((a, b) => $"{a}<br>{b}"));
        }

        public void CreateAppendix(List<UnmappedField> fields)
        {
            string appendix = _appendixTemplate;
            if ((fields?.Any() ?? false))
            {
                var lines = new List<string>();
                foreach (var field in fields)
                {
                    string line = _appendixLineTemplate.Replace("{{Key}}", field.Key);
                    line = line.Replace("{{Value}}", field.Value);
                    line = line.Replace("{{PosNr}}", field.PositionNumber);
                    line = line.Replace("{{Description}}", field.Description ?? "");

                    lines.Add(line);
                }

                appendix = appendix.Replace("{{AppendixLines}}", lines.Aggregate((a, b) => $"{a}{b}"));
            }
            else
            {
                appendix = appendix.Replace("{{AppendixLines}}", "Keine");
            }

            _currentState = _currentState.Replace("{{AppendixHTML}}", appendix);
        }

        public string CreateInvoice()
        {

            _currentState = PlaceholderProcessor.ReplacePlaceholders(_currentState, new DocumentLabels(), _humanReadableRepresentationConfiguration);
            _currentState = PlaceholderProcessor.CleanupPlaceholders(_currentState);
            return _currentState;
        }
    }
}