using System;
using System.Threading.Tasks;
using System.IO;
using Elwig.Helpers;

namespace Elwig.Documents {
    public abstract class Document : IDisposable {

        private TempFile? PdfFile = null;

        public string DataPath;
        public int CurrentNextSeason;
        public string? DocumentId;
        public string Title;
        public string Author;
        public string Header;
        public string Footer;
        public DateTime Date;

        public Document(string title) {
            var c = App.Client;
            DataPath = App.DataPath;
            CurrentNextSeason = Utils.CurrentNextSeason;
            Title = title;
            Author = App.Client.NameFull;
            Header = $"<h1>{c.Name}</h1>";
            Footer = Utils.GenerateFooter("<br/>", " \u00b7 ")
                .Item(c.NameFull).NextLine()
                .Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextLine()
                .Item(c.EmailAddress).Item(c.Website).Item("Betriebs-Nr.", c.LfbisNr).Item("UID", c.UstIdNr).NextLine()
                .Item("BIC", c.Bic).Item("IBAN", c.Iban)
                .ToString();
            Date = DateTime.Today;
        }

        ~Document() {
            Dispose();
        }

        public void Dispose() {
            PdfFile?.Dispose();
            PdfFile = null;
            GC.SuppressFinalize(this);
        }

        private Task<string> Render() {
            string name;
            if (this is BusinessLetter) {
                name = "BusinessLetter";
            } else if (this is DeliveryNote) {
                name = "DeliveryNote";
            } else {
                throw new InvalidOperationException("Invalid document object");
            }
            return Render(name);
        }

        private Task<string> Render(string name) {
            return Html.CompileRenderAsync(name, this);
        }

        public async Task Generate() {
            var pdf = new TempFile("pdf");
            using (var tmpHtml = new TempFile("html")) {
                await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
                await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
            }
            PdfFile = pdf;
        }

        public void SaveTo(string pdfPath) {
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
            File.Copy(PdfFile.FilePath, pdfPath);
        }

        public async Task Print(int copies = 1) {
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
            await Pdf.Print(PdfFile.FilePath, copies);
        }

        public void Show() {
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
            Pdf.Show(PdfFile.NewReference(), Title);
        }
    }
}