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 Document(string title) {
            var c = App.Client;
            DataPath = App.DataPath;
            Title = title;
            Header = $"<h1>{c.Name}</h1>";
            Footer = $"{c.NameFull}<br/>" +
                $"{c.Address} \u00b7 {c.Plz} {c.Ort} \u00b7 Österreich \u00b7 " +
                $"Tel.: {c.PhoneNr} \u00b7 Fax: {c.FaxNr}<br/>{c.EmailAddress} \u00b7 {c.Website} \u00b7 " +
                $"Betriebs-Nr.: {c.LfbisNr} \u00b7 UID: {c.UstId}<br/>" +
                $"BIC: {c.Bic} \u00b7 IBAN: {c.Iban}";
            Date = DateTime.Today;
        }

        ~Document() {
            Dispose();
        }

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

        public string DataPath { get; set; }
        public string Title { get; set; }
        public string Header { get; set; }
        public string Footer { get; set; }
        public DateTime Date { get; set; }

        private async 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 await 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());
                await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
            }
            Pdf.UpdateMetadata(pdf.FilePath, Title, App.Client.NameFull);
            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);
        }
    }
}