using Microsoft.AspNetCore.Mvc;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SolarPower.Models;
using SolarPower.Models.PowerStation;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;
using NPOI.SS.Util;
using NPOI.SS.UserModel.Charts;

namespace SolarPower.Controllers
{
    public class PowerGenerationController : MyBaseController<PowerGenerationController>
    {
        private readonly IElectricitySoldRecordRepository electricitySoldRecordRepository;
        private readonly IPowerStationRepository powerStationRepository;

        public PowerGenerationController(IElectricitySoldRecordRepository electricitySoldRecordRepository, IPowerStationRepository powerStationRepository) : base()
        {
            this.electricitySoldRecordRepository = electricitySoldRecordRepository;
            this.powerStationRepository = powerStationRepository;
        }
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public async Task<ApiResult<List<Generation>>> GetGenerationList (SearchGeneration post)
        {
            ApiResult<List<Generation>> apiResult = new ApiResult<List<Generation>>();
            try
            {
                var GenerationList = await electricitySoldRecordRepository.GetGenerationList(post);
                apiResult.Data = GenerationList;
                apiResult.Code = "0000";
            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                apiResult.Msg = exception.ToString();

                Logger.LogError("【" + controllerName + "/" + actionName + "】" + "info=" + System.Text.Json.JsonSerializer.Serialize(post));
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
            }
            return apiResult;
        }

        public FileResult ExportExcelAsync(string post)
        {
            var postObject = JsonConvert.DeserializeObject<SearchGeneration2>(post);
            var workbook = new XSSFWorkbook();

            #region excel設定
            IFont font12 = workbook.CreateFont();
            font12.FontName = "新細明體";
            font12.FontHeightInPoints = 12;
            ICellStyle style12yellow = workbook.CreateCellStyle();
            style12yellow.SetFont(font12);
            style12yellow.Alignment = HorizontalAlignment.Center;
            style12yellow.VerticalAlignment = VerticalAlignment.Center;
            style12yellow.BorderTop = BorderStyle.Thin;
            style12yellow.BorderBottom = BorderStyle.Thin;
            style12yellow.BorderLeft = BorderStyle.Thin;
            style12yellow.BorderRight = BorderStyle.Thin;
            style12yellow.FillForegroundColor = IndexedColors.Yellow.Index;
            style12yellow.FillPattern = FillPattern.SolidForeground;
            style12yellow.WrapText = true;

            ICellStyle style12lightgreen = workbook.CreateCellStyle();
            style12lightgreen.SetFont(font12);
            style12lightgreen.Alignment = HorizontalAlignment.Center;
            style12lightgreen.VerticalAlignment = VerticalAlignment.Center;
            style12lightgreen.BorderTop = BorderStyle.Thin;
            style12lightgreen.BorderBottom = BorderStyle.Thin;
            style12lightgreen.BorderLeft = BorderStyle.Thin;
            style12lightgreen.BorderRight = BorderStyle.Thin;
            style12lightgreen.FillForegroundColor = IndexedColors.LightGreen.Index;
            style12lightgreen.FillPattern = FillPattern.SolidForeground;
            style12lightgreen.WrapText = true;

            ICellStyle style12green = workbook.CreateCellStyle();
            style12green.SetFont(font12);
            style12green.Alignment = HorizontalAlignment.Center;
            style12green.VerticalAlignment = VerticalAlignment.Center;
            style12green.BorderTop = BorderStyle.Thin;
            style12green.BorderBottom = BorderStyle.Thin;
            style12green.BorderLeft = BorderStyle.Thin;
            style12green.BorderRight = BorderStyle.Thin;
            style12green.FillForegroundColor = IndexedColors.BrightGreen.Index;
            style12green.FillPattern = FillPattern.SolidForeground;
            style12green.WrapText = true;

            ICellStyle style12orange = workbook.CreateCellStyle();
            style12orange.SetFont(font12);
            style12orange.Alignment = HorizontalAlignment.Center;
            style12orange.VerticalAlignment = VerticalAlignment.Center;
            style12orange.BorderTop = BorderStyle.Thin;
            style12orange.BorderBottom = BorderStyle.Thin;
            style12orange.BorderLeft = BorderStyle.Thin;
            style12orange.BorderRight = BorderStyle.Thin;
            style12orange.FillForegroundColor = IndexedColors.LightOrange.Index;
            style12orange.FillPattern = FillPattern.SolidForeground;
            style12orange.WrapText = true;
            #endregion

            foreach (var objects in postObject.PowerStation)
            {
                var sheet = workbook.CreateSheet(objects.Name);

                SearchGeneration select_Table = new SearchGeneration
                {
                    Date = postObject.Date,
                    PowerstationId = Convert.ToInt32(objects.Value),
                    DateType = postObject.DateType
                };
                var result = GetGenerationList(select_Table);
                CellRangeAddress region;
                IRow row ;
                ICell cell ;
                for(var a = 0;a<15;a++)
                {
                    sheet.SetColumnWidth(a, 6 * 160 * 4);
                }
                
                row = sheet.CreateRow(0);
                row.HeightInPoints = 40;
                #region row-0
                cell = row.CreateCell(0);
                cell.SetCellValue(objects.Name); 
                region = new CellRangeAddress(0, 0, 0, 2);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(2);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(3);
                cell.SetCellValue("CBA");
                region = new CellRangeAddress(0, 0, 3, 5);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(5);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(6);
                cell.SetCellValue("監控系統");
                region = new CellRangeAddress(0, 0, 6, 7);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(7);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(8);
                cell.SetCellValue("Actual Rev.");
                region = new CellRangeAddress(0, 0, 8, 9);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(9);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(10);
                cell.SetCellValue("平均發電度數小計\r(/kW)");
                region = new CellRangeAddress(0, 0, 10, 14);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12yellow;

                cell = row.CreateCell(14);
                cell.CellStyle = style12yellow;
                #endregion
                
                row = sheet.CreateRow(1);
                row.HeightInPoints = 40;
                #region row-1
                cell = row.CreateCell(0);
                cell.SetCellValue("計算區間");
                region = new CellRangeAddress(1, 2, 0, 2);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12green;

                cell = row.CreateCell(1);
                cell.CellStyle = style12green;
                cell = row.CreateCell(2);
                cell.CellStyle = style12green;

                cell = row.CreateCell(3);
                cell.SetCellValue("建置容量\r(kW)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(4);
                cell.SetCellValue("發電度數\r(/kW /日)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(5);
                cell.SetCellValue("售電單價\r(NT$/度)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(6);
                cell.SetCellValue("建置容量\r(kW)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(7);
                cell.SetCellValue("售電單價\r(NT$/度)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(8);
                cell.SetCellValue("建置容量\r(kW)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(9);
                cell.SetCellValue("建置容量\r(kW)");
                cell.CellStyle = style12green;

                cell = row.CreateCell(10);
                cell.SetCellValue("CBA");
                cell.CellStyle = style12lightgreen;
                cell = row.CreateCell(11);
                cell.SetCellValue("監控系統");
                cell.CellStyle = style12lightgreen;
                cell = row.CreateCell(12);
                cell.SetCellValue("v.s CBA");
                cell.CellStyle = style12lightgreen;
                cell = row.CreateCell(13);
                cell.SetCellValue("Actual");
                cell.CellStyle = style12lightgreen;
                cell = row.CreateCell(14);
                cell.SetCellValue("v.s CBA");
                cell.CellStyle = style12lightgreen;

                #endregion

                row = sheet.CreateRow(3);
                row.HeightInPoints = 40;
                #region row-3
                cell = row.CreateCell(0);
                cell.SetCellValue("起日");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(1);
                cell.SetCellValue("訖日");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(2);
                cell.SetCellValue("天數");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(3);
                cell.SetCellValue("發電效能");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(4);
                cell.SetCellValue("總發電量\r(度數)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(5);
                cell.SetCellValue("總售電收入\r(NT$)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(6);
                cell.SetCellValue("總發電量\r(度數)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(7);
                cell.SetCellValue("總售電收入\r(NT$)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(8);
                cell.SetCellValue("總發電量\r(度數)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(9);
                cell.SetCellValue("總售電收入\r(NT$)");
                cell.CellStyle = style12orange;

                cell = row.CreateCell(10);
                cell.SetCellValue("平均發電度數明細\r(/kW/日)");
                region = new CellRangeAddress(3, 3, 10, 14);
                sheet.AddMergedRegion(region);
                cell.CellStyle = style12orange;

                cell = row.CreateCell(14);
                cell.CellStyle = style12orange;

                #endregion

                int index = 4;
                var totalday = 0;
                var totalCBA = 0.0;
                var totalReal = 0.0;
                var totalAct = 0.0;
                var cap = 0.0;
                var rate = 0.0;
                var cbAkwh = 0.0;
                foreach (var day in result.Result.Data)
                {
                    
                    totalReal += day.realKWH;
                    totalAct += day.actualkwh;
                    cap = day.capacity;
                    rate = day.rate;
                    cbAkwh = day.CBAkwh;
                    row = sheet.CreateRow(index);
                    row.HeightInPoints = 40;
                    #region row-4++
                    cell = row.CreateCell(0);
                    cell.SetCellValue(day.StartAt);
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(1);
                    cell.SetCellValue(day.EndAt);
                    cell.CellStyle = style12green;

                    var forday = Convert.ToDateTime(day.EndAt).Subtract(Convert.ToDateTime(day.StartAt)).Days + 1;
                    totalday += forday;
                    cell = row.CreateCell(2);
                    cell.SetCellValue(forday + "天");
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(3);
                    cell.SetCellValue(To2(day.CBAeff) + "%");
                    cell.CellStyle = style12green;

                    var cbakwh = day.CBAkwh * day.CBAeff * forday * day.capacity * 0.01;
                    totalCBA += cbakwh;
                    cell = row.CreateCell(4);
                    cell.SetCellValue(To2(cbakwh));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(5);
                    cell.SetCellValue(To2(cbakwh * day.rate));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(6);
                    cell.SetCellValue(To2(day.realKWH));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(7);
                    cell.SetCellValue(To2(day.realMoney));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(8);
                    cell.SetCellValue(To2(day.actualkwh));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(9);
                    cell.SetCellValue(To2(day.actualMoney));
                    cell.CellStyle = style12green;

                    cell = row.CreateCell(10);
                    var cbak = (day.capacity == 0 || forday == 0) ? 0 :(cbakwh / day.capacity / forday);
                    cell.SetCellValue(To2(cbak));
                    cell.CellStyle = style12lightgreen;

                    cell = row.CreateCell(11);
                    var realk = (day.capacity == 0 || forday == 0) ? 0 : (day.realKWH / day.capacity / forday);
                    cell.SetCellValue(To2(realk));
                    cell.CellStyle = style12lightgreen;

                    cell = row.CreateCell(12);
                    cell.SetCellValue( ((cbak == 0) ? 0 : To2((realk / cbak - 1)*100)) + "%");
                    cell.CellStyle = style12lightgreen;

                    cell = row.CreateCell(13);
                    var actk = (day.capacity == 0 || forday == 0) ? 0 : (day.actualkwh / day.capacity / forday);
                    cell.SetCellValue(To2(actk));
                    cell.CellStyle = style12lightgreen;

                    cell = row.CreateCell(14);
                    cell.SetCellValue( ((cbak == 0) ? 0 : To2((actk / cbak - 1)*100)) + "%");
                    cell.CellStyle = style12lightgreen;
                    #endregion

                    index++;
                }

                row = sheet.CreateRow(2);
                row.HeightInPoints = 40;
                #region row-2
                cell = row.CreateCell(3);
                cell.SetCellValue(To2(cap));
                cell.CellStyle = style12green;

                cell = row.CreateCell(4);
                cell.SetCellValue(cbAkwh);
                cell.CellStyle = style12green;

                cell = row.CreateCell(5);
                cell.SetCellValue(To2(rate));
                cell.CellStyle = style12green;

                cell = row.CreateCell(6);
                cell.SetCellValue(To2(cap));
                cell.CellStyle = style12green;

                cell = row.CreateCell(7);
                cell.SetCellValue(To2(rate));
                cell.CellStyle = style12green;

                cell = row.CreateCell(8);
                cell.SetCellValue(To2(cap));
                cell.CellStyle = style12green;

                cell = row.CreateCell(9);
                cell.SetCellValue(To2(rate));
                cell.CellStyle = style12green;


                var CBAkwh = (cap == 0|| totalday == 0)? 0 : totalCBA / cap / totalday;
                cell = row.CreateCell(10);
                cell.SetCellValue(To2(CBAkwh));
                cell.CellStyle = style12lightgreen;

                var Realkwh = (cap == 0 || totalday == 0) ? 0 : totalReal / cap / totalday;
                cell = row.CreateCell(11);
                cell.SetCellValue(To2(Realkwh));
                cell.CellStyle = style12lightgreen;

                cell = row.CreateCell(12);
                cell.SetCellValue(((CBAkwh == 0) ? 0 : To2((Realkwh / CBAkwh - 1) * 100)) + "%");
                cell.CellStyle = style12lightgreen;

                var Actkwh = (cap == 0 || totalday == 0) ? 0 : totalAct / cap / totalday;
                cell = row.CreateCell(13);
                cell.SetCellValue(To2(Actkwh));

                cell.CellStyle = style12lightgreen;
                cell = row.CreateCell(14);
                cell.SetCellValue(((CBAkwh == 0) ? 0 : To2((Actkwh / CBAkwh -1) * 100))+"%");
                cell.CellStyle = style12lightgreen;

                #endregion



                if(result.Result.Data.Count >0)
                {
                    var drawing = sheet.CreateDrawingPatriarch();
                    IClientAnchor anchor = drawing.CreateAnchor(0, 0, 0, 0, 16, 1, 25, 9);
                    var chart = drawing.CreateChart(anchor);
                    IChartLegend legend = chart.GetOrCreateLegend();
                    legend.Position = LegendPosition.Bottom;
                    ILineChartData<double, double> data = chart.ChartDataFactory.CreateLineChartData<double, double>();
                    IBarChartData<double, double> data2 = chart.ChartDataFactory.CreateBarChartData<double, double>();
                    IChartAxis bottomAxis = chart.ChartAxisFactory.CreateCategoryAxis(AxisPosition.Bottom);
                    IValueAxis leftAxis = chart.ChartAxisFactory.CreateValueAxis(AxisPosition.Left);
                    bottomAxis.Crosses = AxisCrosses.AutoZero;
                    //bottomAxis.MinorTickMark = AxisTickMark.In;
                    leftAxis.Crosses = AxisCrosses.AutoZero;
                    IChartDataSource<double> xs = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(4, result.Result.Data.Count + 3, 0, 0));
                    
                    IChartDataSource<double> ys1 = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(4, result.Result.Data.Count + 3, 4, 4));
                    IChartDataSource<double> ys2 = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(4, result.Result.Data.Count + 3, 6, 6));
                    IChartDataSource<double> ys3 = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(4, result.Result.Data.Count + 3, 8, 8));

                    var Cba = data.AddSeries(xs, ys1);
                    Cba.SetTitle("CBA預估總發電量(度數)");
                    var Real = data.AddSeries(xs, ys2);
                    Real.SetTitle("監控系統總發電量(度數)");
                    var Act = data.AddSeries(xs, ys3);
                    Act.SetTitle("台電售電量(度數)");
                    //chart.Plot(data2, bottomAxis, leftAxis);
                    chart.Plot(data, bottomAxis, leftAxis);
                    
                }
                
            }





            var ms = new NpoiMemoryStream
            {
                AllowClose = false
            };
            workbook.Write(ms);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);
            return File(ms, "application/vnd.ms-excel", "電廠發電效能統計.xlsx");
        }



        public double To2 (double a)
        {
            var b = Math.Round(a, 2);
            return b;
        }
    }

    


}
