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) {
            DataPath = App.DataPath;
            Title = title;
            Header = $"<h1>{App.Client.Name}</h1>";
            Footer = App.Client.NameFull;
            Date = DateTime.Today;
        }

        ~Document() {
            Dispose();
        }

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

        public string DataPath { get; set; }

        public string Title { get; set; }

        public string Header { get; set; }

        public string Footer { get; set; }

        public string FullDateString {
            get => Date.ToString("dddd, d. MMMM yyyy");
        }

        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, "Winzergenossenschaft für Matzen und Umgebung reg. Gen.m.b.H.");
            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() {
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
            Pdf.Print(PdfFile.FilePath);
        }

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