using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels.Entity;
using Performance.EntityModels.Other;
using Performance.Services;
using System.Collections.Generic;
using Microsoft.AspNetCore.StaticFiles;
using System;
using System.IO;
using Newtonsoft.Json;

namespace Performance.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AttendanceController : ControllerBase
    {
        private readonly AttendanceService _attendanceService;
        public AttendanceController(
            AttendanceService attendanceService
            )
        {
            _attendanceService = attendanceService;
        }
        /*
         
        per_attendance   考勤-调动记录表 
        per_attendance_type   考勤-考勤类型 
        per_attendance_vacation   考勤-考勤记录表 

        view_attendance  考勤视图

         */
        /// <summary>
        /// 查询绩效考勤记录
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpGet("GetAttendance/{allotId}")]
        public ApiResponse<List<AttendanceStatistics>> GetAttendance(int allotId)
        {
            // 查询考勤视图，并按照设计图做格式转换 仅查询开始结束
            var result = _attendanceService.GetAttendance(allotId);

            return result;
        }

        #region 调动记录

        /// <summary>
        /// 查询绩效调动记录
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpGet("CallIn/{allotId}")]
        public ApiResponse<List<view_attendance>> GetCallIn(int allotId)
        {
            // 查询考勤视图，并按照设计图做格式转换 仅查询调入
            return _attendanceService.GetCallIn(allotId);
        }

        /// <summary>
        /// 返回HandsonTable格式调动记录
        /// </summary>
        /// <returns></returns>
        [HttpGet("CallIn/GetBatch")]
        [ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
        public ApiResponse GetBatchCallInHandsonTable(int allotId)
        {
            // 返回HandsonTable格式调动记录
            return new ApiResponse(ResponseType.OK, _attendanceService.GetBatchCallInHandsonTable(allotId));
        }

        /// <summary>
        /// 批量插入调动记录
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("CallIn/Batch/{allotId}")]
        public ApiResponse BatchCallIn(int allotId, int hospitalId, SaveCollectData request)
        {
            // obj自己定义结构
            // 批量插入调动记录，插入前需要删除所有后重新插入

            // 需要验证工号和姓名是否与“人员字典”（per_employee）完全匹配，不匹配则返回表格错误提示
            // 需要验证核算组别和核算单元是否与“核算单元及组别”（cof_accounting）完全匹配，不匹配则返回表格错误提示

            // 表格错误提醒参考PersonService.CreatePerson方法
            return _attendanceService.BatchCallIn(allotId, hospitalId, request);
        }
        #endregion

        #region 考勤类型
        /// <summary>
        /// 查询绩效考勤类型
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("Type/{allotId},{hospitalId}")]
        public ApiResponse<List<per_attendance_type>> GetAttendanceType(int allotId, int hospitalId)
        {
            return _attendanceService.GetAttendanceType(allotId);
        }
        /// <summary>
        /// 新增或修改考勤类型
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <param name="attendanceType"></param>
        /// <returns></returns>
        [HttpPost("Type/Edit/{allotId},{hospitalId}")]
        public ApiResponse<AttendanceType> InsertAttendanceType(int allotId, int hospitalId, AttendanceType attendanceType)
        {
            // obj自己定义结构
            return _attendanceService.InsertAttendanceType(allotId, hospitalId, attendanceType);
        }
        /// <summary>
        /// 删除考勤类型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("Type/Delete/{id}")]
        public ApiResponse DeleteAttendanceType(int id)
        {
            // 删除前需要验证当前类型是否被使用，如果被使用则禁止删除
            return _attendanceService.DeleteAttendanceType(id);
        }
        #endregion

        #region 考勤记录
        /// <summary>
        /// 返回HandsonTable格式考勤记录
        /// </summary>
        /// <returns></returns>
        [HttpGet("Vacation")]
        [ProducesResponseType(typeof(HandsonTable), StatusCodes.Status200OK)]
        public ApiResponse GetAttendanceVacationHandsonTable(int allotId)
        {
            // 返回HandsonTable格式考勤记录
            return new ApiResponse(ResponseType.OK, _attendanceService.GetAttendanceVacationHandsonTable(allotId));
        }

        /// <summary>
        /// 查询考勤记录
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <returns></returns>
        [HttpGet("Vacation/{allotId},{hospitalId}")]
        public ApiResponse<List<RecordAttendcance>> GetAttendanceVacation(int allotId)
        {
            return _attendanceService.GetAttendanceVacation(allotId);
        }

        /// <summary>
        /// 批量插入考勤记录，插入前需要删除所有后重新插入
        /// </summary>
        /// <param name="allotId"></param>
        /// <param name="hospitalId"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("Vacation/Batch/{allotId}")]
        public ApiResponse AttendanceBatch(int allotId, int hospitalId, SaveCollectData request)
        {
            // obj自己定义结构
            // 批量插入考勤记录，插入前需要删除所有后重新插入
            // 需要验证考勤类型是否正确
            // 需要验证工号和姓名是否与“人员字典”（per_employee）完全匹配，不匹配则返回表格错误提示

            // 表格错误提醒参考PersonService.CreatePerson方法
            return _attendanceService.AttendanceBatch(allotId, hospitalId, request);
        }
        #endregion

        /// <summary>
        /// 考勤结果统计
        /// </summary>
        /// <param name="allotId"></param> 
        /// <returns></returns>
        [HttpGet("statistics/{allotId}")]
        public ApiResponse<List<AttendanceStatistics>> GetAttendanceStatistics(int allotId)
        {
            // 返回结果参考接口 employee/apr/getdeptdetail
            return _attendanceService.GetAttendanceStatistics(allotId);
        }

        #region 下载

        /// <summary>
        /// 初始考勤记录下载
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/attendance/{allotId}")]
        public IActionResult DownloadAttendance(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "核算单元名称", Name = nameof(AttendanceStatistics.AccountingUnit) },
                new ExcelDownloadHeads { Alias = "科室名称", Name =  nameof(AttendanceStatistics.Department) },
                new ExcelDownloadHeads { Alias = "姓名", Name =  nameof(AttendanceStatistics.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name =  nameof(AttendanceStatistics.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "人员类别", Name =  nameof(AttendanceStatistics.UnitType) },
                new ExcelDownloadHeads { Alias = "在科开始时问", Name =  nameof(AttendanceStatistics.BeginDate) },
                new ExcelDownloadHeads { Alias = "在科结束时间", Name =  nameof(AttendanceStatistics.EndDate) },
            };
            var result = _attendanceService.GetAttendance(allotId).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _attendanceService.ExcelDownload(rows, "初始考勤记录", allotId, excelDownloadHeads);

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }


        /// <summary>
        /// 考勤记录下载
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/vacation/{allotId}")]
        public IActionResult DownloadVacation(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "姓名", Name = nameof(RecordAttendcance.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name = nameof(RecordAttendcance.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "考勤类型", Name = nameof(RecordAttendcance.AttendanceName) },
                new ExcelDownloadHeads { Alias = "开始时问", Name = nameof(RecordAttendcance.BegDate) },
                new ExcelDownloadHeads { Alias = "结束时间", Name = nameof(RecordAttendcance.EndDate) },
                new ExcelDownloadHeads { Alias = "天数", Name = nameof(RecordAttendcance.Days) },
            };

            var result = _attendanceService.GetAttendanceVacation(allotId).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _attendanceService.ExcelDownload(rows, "考勤记录", allotId, excelDownloadHeads);

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }


        /// <summary>
        /// 调动记录下载
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/callin/{allotId}")]
        public IActionResult DownloadCallIn(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "姓名", Name = nameof(view_attendance.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name = nameof(view_attendance.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "调入核算单元", Name = nameof(view_attendance.AccountingUnit) },
                new ExcelDownloadHeads { Alias = "调入组别", Name = nameof(view_attendance.UnitType) },
                new ExcelDownloadHeads { Alias = "调入时间", Name = nameof(view_attendance.AttendanceDate) },
            };

            var result = _attendanceService.GetCallIn(allotId).Data;
            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _attendanceService.ExcelDownload(rows, "调动记录", allotId, excelDownloadHeads);

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
        }

        /// <summary>
        /// 生成最终考勤结果下载
        /// </summary>
        /// <param name="allotId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("download/statistics/{allotId}")]
        public IActionResult DownloadStatistics(int allotId)
        {
            List<ExcelDownloadHeads> excelDownloadHeads = new List<ExcelDownloadHeads>()
            {
                new ExcelDownloadHeads { Alias = "科室名称", Name = nameof(AttendanceStatistics.Department) },
                new ExcelDownloadHeads { Alias = "姓名", Name = nameof(AttendanceStatistics.PersonnelName) },
                new ExcelDownloadHeads { Alias = "员工号", Name = nameof(AttendanceStatistics.PersonnelNumber) },
                new ExcelDownloadHeads { Alias = "人员类别", Name = nameof(AttendanceStatistics.UnitType) },
                new ExcelDownloadHeads { Alias = "开始时问", Name = nameof(AttendanceStatistics.BeginDate) },
                new ExcelDownloadHeads { Alias = "结束时间", Name = nameof(AttendanceStatistics.EndDate) },
            };
            var type = _attendanceService.GetAttendanceType(allotId);
            foreach (var item in type.Data)
            {
                excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = item.AttendanceName, Name = item.AttendanceName });
            }
            excelDownloadHeads.Add(new ExcelDownloadHeads() { Alias = "考勤天数", Name = "AttendanceDays" });

            var result = _attendanceService.GetAttendanceStatistics(allotId).Data;

            var ser = JsonConvert.SerializeObject(result);
            var rows = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(ser);

            var filepath = _attendanceService.ExcelDownload(rows, "最终考勤结果", allotId, excelDownloadHeads);

            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(filepath, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filepath);
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(fileInfo.Name));
            /*var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院人员绩效模板.xlsx");
            var memoryStream = new MemoryStream();
            using (var stream = new FileStream(path, FileMode.Open))
            {
                stream.CopyToAsync(memoryStream).Wait();
            }
            memoryStream.Seek(0, SeekOrigin.Begin);
            var provider = new FileExtensionContentTypeProvider();
            var memi = provider.Mappings[".xlsx"];
            return File(memoryStream, memi, Path.GetFileName(path));*/

        }
        #endregion

    }
}
