using BoFilTest.Utils;
using NPOI.SS.UserModel;
using System;
using System.IO;
using System.Text;

namespace BoFilTest.Export
{
    class ExcelTemplate
    {
        private readonly IWorkbook workbook;
        private readonly ISheet sheet;
        private readonly short DateDataFormat;

        static IWorkbook LoadTemplate(string templateName)
        {
            ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = Encoding.Default.CodePage;
            using (FileStream file = new FileStream(templateName, FileMode.Open, FileAccess.Read))
                return WorkbookFactory.Create(file);
        }

        public ExcelTemplate(string templateName, string sheetName)
        {
            this.workbook = LoadTemplate(templateName);

            // Remove all but the target sheets
            while (!sheetName.Equals(this.workbook.GetSheetAt(0).SheetName))
                this.workbook.RemoveSheetAt(0);

            for (int i = 1; i < this.workbook.NumberOfSheets; ++i)
                this.workbook.RemoveSheetAt(i);

            if (this.workbook.NumberOfSheets == 0)
                throw new InvalidOperationException(Translated.NotYet("Undefined sheet: {0}", sheetName));

            this.sheet = this.workbook.GetSheetAt(0);

            this.DateDataFormat = workbook.CreateDataFormat().GetFormat("yyyy-MM-dd HH:mm");
        }

        public void SetDateStyleOn(ICell cell)
        {
            ICellStyle style = null;

            style = workbook.CreateCellStyle();

            if (cell.CellStyle != null)
            {
                style.CloneStyleFrom(cell.CellStyle);
            }

            cell.CellStyle = style;
            style.DataFormat = DateDataFormat;
        }

        private string GenerateFilename(TranslationKey filenameKey, string filenameTag)
        {
            return Translated.FromKey(filenameKey, filenameTag, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
        }

        public ICell GetOrCreateCell(Tuple<int, int> where)
        {
            var row = this.sheet.GetRow(where.Item2);
            if (row == null)
                row = this.sheet.CreateRow(where.Item2);
            var rowStyle = row.RowStyle;
            var cell = row.GetCell(where.Item1);
            if (cell == null)
                cell = row.CreateCell(where.Item1);
            var style = cell.CellStyle;
            return cell;
        }

        /// <summary>
        /// Write to a datetime-tagged filename with the given pattern
        /// </summary>
        /// <param name="filenameKey"></param>
        /// <returns>The generated filename</returns>
        public string Write(string targetPath, TranslationKey filenameKey, string filenameTag)
        {
            Directory.CreateDirectory(targetPath);

            var filename = GenerateFilename(filenameKey, filenameTag);
            using (FileStream file = File.Create(Path.Combine(targetPath, filename)))
                workbook.Write(file);

            return filename;
        }
    }
}
