using FrontendWebApi.Models;
using iTextSharp.text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.Util;
using Org.BouncyCastle.Crypto.Agreement.JPake;
using Repository.BackendRepository.Interface;
using Repository.FrontendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Image = System.Drawing.Image;
using System.IdentityModel.Tokens.Jwt;
using System.Net;

namespace FrontendWebApi.ApiControllers
{
    //[Route("api/[controller]")]
    //[ApiController]
    public class OperationLogController : MyBaseApiController<OperationLogController>
    {
        private readonly IBackendRepository backendRepository;
        private string operationFileSaveAsPath = "";

        public OperationLogController(IBackendRepository backendRepository)
        {
            this.backendRepository = backendRepository;
            operationFileSaveAsPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "upload", "operation");
        }


        [HttpPost]
        [Route("api/OperationLog/GetList")]
        public async Task<ActionResult<ApiResult<List<OperationLogOutput>>>> GetList([FromBody] PageResult<OperationLogInput> pageResult) 
        {

            ApiResult<List<OperationLogOutput>> apiResult = new ApiResult<List<OperationLogOutput>>(jwt_str);
            if (!jwtlife)
            {
                apiResult.Code = "5000";
                return BadRequest(apiResult);
            }
            try
            {
                string pageQuery = pageResult.isEnable ? " LIMIT @pageSize OFFSET @skip" : "";
                // 取得資料
                var logList = await backendRepository.GetAllAsync<OperationLogOutput>($@" 
                                select ui.full_name as 'user_name' ,ol.* from operation_log ol 
                                LEFT JOIN userinfo ui on ui.userinfo_guid COLLATE utf8mb4_unicode_ci = ol.user_guid
                                WHERE ol.operation_type = @operation_type AND ol.building_tag = @building_tag AND
                                ol.created_at >= @start_time AND ol.created_at <= @end_time
                                {pageQuery}",
                                new { 
                                    pageSize = pageResult.pageSize , 
                                    skip = (pageResult.currentPage - 1) * pageResult.pageSize,
                                    operation_type = pageResult.data?.operation_type,
                                    building_tag = pageResult.data?.building_tag,
                                    start_time = pageResult.data?.start_time,
                                    end_time = pageResult.data?.end_time,
                                });

                // 設定呈現紀錄內容
                foreach (var log in logList) {
                    if (log.parameter == null) {
                        continue;
                    }
                    switch (log.operation_type) {
                        case 1:
                            var chaName = JsonConvert.DeserializeObject<ChangeName>(log.parameter);
                            if (chaName == null) continue;
                            log.content = chaName.TagName + ":" + chaName.ChangeN;
                            break;
                        case 2:
                            var schedule = JsonConvert.DeserializeObject<SaveSchedule>(log.parameter);
                            if (schedule == null) continue;
                            var contentArr = new List<string>() {
                                "編號:" + schedule.light_schedule_guid,
                                "名稱:" + schedule.full_name,
                            };

                            if (log.action_name == "修改") {
                                contentArr.Add("修改內容:" + string.Join("、", schedule.changeNames));
                            }
                            log.content = string.Join("\n",contentArr);
                            break;
                    }
                }
                apiResult.Code = "0000";
                apiResult.Data = logList;

            }
            catch (Exception exception)
            {
                apiResult.Code = "9999";
                Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
                return Ok(apiResult);
            }
            return Ok(apiResult);

        }

        [HttpPost]
        [Route("api/OperationLog/ExportList")]
        public async Task<FileResult> ExportList([FromBody] OperationLogExportInput input)
        {
            List<OperationLogOutput> result = new List<OperationLogOutput>();
            if (input.isNiagara)
            {
                result = input.exportList;
            }
            else
            {
                PageResult<OperationLogInput> pageResult = input.listInput;
                pageResult.isEnable = false; 
                result = ((ApiResult<List<OperationLogOutput>>)((OkObjectResult)(await this.GetList(pageResult)).Result).Value).Data.ToList();
            }

            var workbook = new XSSFWorkbook();
            #region excel設定
            IFont font12 = workbook.CreateFont();
            font12.FontName = "新細明體";
            font12.FontHeightInPoints = 12;
            ICellStyle style12 = workbook.CreateCellStyle();
            style12.SetFont(font12);
            style12.Alignment = HorizontalAlignment.Center;
            style12.VerticalAlignment = VerticalAlignment.Center;
            IFont font12Times = workbook.CreateFont();
            font12Times.FontName = "Times New Roman";
            font12Times.FontHeightInPoints = 12;
            IFont font18 = workbook.CreateFont();
            font18.FontName = "新細明體";
            font18.FontHeightInPoints = 18;
            font18.IsBold = true;
            ICellStyle styleTitle18 = workbook.CreateCellStyle();
            styleTitle18.SetFont(font18);
            styleTitle18.Alignment = HorizontalAlignment.Center;
            styleTitle18.VerticalAlignment = VerticalAlignment.Center;
            ICellStyle styleLeft12 = workbook.CreateCellStyle();
            styleLeft12.SetFont(font12);
            styleLeft12.Alignment = HorizontalAlignment.Left;
            styleLeft12.VerticalAlignment = VerticalAlignment.Center;
            ICellStyle styleLine12 = workbook.CreateCellStyle();
            styleLine12.SetFont(font12);
            styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            styleLine12.VerticalAlignment = VerticalAlignment.Center;
            styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            ICellStyle stylein12 = workbook.CreateCellStyle();
            stylein12.SetFont(font12Times);
            stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
            stylein12.VerticalAlignment = VerticalAlignment.Center;
            stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            stylein12.WrapText = true;
            #endregion

            var sheet = workbook.CreateSheet("電表報表");
            int RowPosition = 0;
            if (result.Count > 0)
            {
                #region set cell
                int ri = 0;
                IRow row = sheet.CreateRow(RowPosition);
                if (!input.isNiagara) { 
                sheet.SetColumnWidth(ri++, 1 * 160 * 12);
                }
                sheet.SetColumnWidth(ri++, 2 * 160 * 12);
                sheet.SetColumnWidth(ri++, 2 * 160 * 12);
                sheet.SetColumnWidth(ri++, 8 * 160 * 12);
                sheet.SetColumnWidth(ri++, 4 * 160 * 12);

                int i = 0;

                ICell cell = row.CreateCell(i++);
                if (!input.isNiagara)
                {
                    cell.SetCellValue("編號");
                    cell.CellStyle = styleLine12;
                    cell = row.CreateCell(i++);
                }
                cell.SetCellValue("操作人");
                cell.CellStyle = styleLine12;
                cell = row.CreateCell(i++);
                cell.SetCellValue("動作");
                cell.CellStyle = styleLine12;

                cell = row.CreateCell(i++);
                cell.SetCellValue("內容");
                cell.CellStyle = stylein12;
                cell = row.CreateCell(i++);
                cell.SetCellValue("紀錄時間");
                cell.CellStyle = styleLine12;
                #endregion

                foreach (var r in result)
                {
                    RowPosition += 1;
                    int k = 3;
                    row = sheet.CreateRow(RowPosition);
                    for (int j = 0; j <= i; j++)
                    {
                        int s = 0;
                        cell = row.CreateCell(j);
                        if (!input.isNiagara && j == s++)
                        {
                            cell.SetCellValue(r.id);
                        }
                        if (j == s++)
                        {
                            cell.SetCellValue(r.user_name);
                        }
                        if (j == s++)
                        {
                            cell.SetCellValue(r.action_name);
                        }

                        if (j == s++)
                        {
                            cell.SetCellValue(r.content);
                        }
                        
                        if (j == s++)
                        {
                            cell.SetCellValue(r.created_at != null ? ((DateTime)r.created_at).ToString("yyyy-MM-dd HH:mm:ss") : null);
                        }

                        cell.CellStyle = style12;
                    }
                }
            }

            var ms = new NpoiMemoryStream
            {
                AllowClose = false
            };
            workbook.Write(ms);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);

            Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");

            return File(ms, "application/vnd.ms-excel", $"操作紀錄_{input.exportOpeTypeName}.xlsx");
        }
    }
}