using FarPoint.Excel;
using FarPoint.Excel.EntityClassLibrary.DrawingVML;
using FarPoint.Win.Spread;
using FarPoint.Win.Spread.CellType.BarCode;
using FCOMMON;
using NetOffice.Extensions.Invoker;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace FBS0000
{
    public partial class rHolidaySummary : fBase
    {
        public rHolidaySummary()
        {
            InitializeComponent();
            Properties.Settings.Default["gwcs"] = FCOMMON.info.CS;
            this.WindowState = FormWindowState.Maximized;
        }

        private void rJobReport_Load(object sender, EventArgs e)
        {
            EnsureVisibleAndUsableSize();

            this.tbMon.Text = DateTime.Now.ToString("yyyy-MM-dd");

            refrehData();
            // this.reportViewer1.RefreshReport();
        }

        void refrehData()
        {

            var dt = DateTime.Parse(this.tbMon.Text);
            ta.Fill(this.dsReport.holydata, FCOMMON.info.Login.gcode, dt.Year.ToString("0000") + "-01-01", dt.ToString("yyyy-MM-dd"));

            //데이터를 재 집계한다.
            this.dsReport.holydatasum.Clear();

            var grp_user = dsReport.holydata.GroupBy(t => t.uid).ToList();
            int curLevel = Math.Max(FCOMMON.info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.holyday));

            foreach (var grp in grp_user)
            {
                //cate group
                var first_user = grp.First();
                if (curLevel < 5 && grp.Key.Equals(FCOMMON.info.Login.no) == false)
                {
                    continue;
                }

                var grp_cate = grp.GroupBy(t => t.cate).ToList();
                foreach (var cate in grp_cate)
                {
                    var newdr = this.dsReport.holydatasum.NewholydatasumRow();
                    var catename = cate.Key;
                    newdr.uid = grp.Key;
                    newdr.uname = first_user.name;
                    newdr.process = first_user.Process;
                    newdr.cate = cate.Key;

                    if (catename.StartsWith("대체"))
                    {
                        newdr.dr = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.DrTime);
                        newdr.cr = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.CrTime);
                        newdr.iwol = cate.Where(t => t.IsiwolNull() == false && t.iwol == true).Sum(t => t.DrTime);


                    }
                    else if (catename.StartsWith("외출"))
                    {

                    }
                    else
                    {
                        //이월과 그렇지 않은 데이터로 분리한다.
                        newdr.drday = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.DrDay);
                        newdr.crday = cate.Where(t => t.IsiwolNull() == true || t.iwol == false).Sum(t => t.CrDay);
                        newdr.iwolday = cate.Where(t => t.IsiwolNull() == false && t.iwol == true).Sum(t => t.DrDay);
                    }

                    if (catename.StartsWith("대체")) newdr.orderno = 99;
                    else if (catename.StartsWith("년차")) newdr.orderno = 1;
                    else if (catename.StartsWith("이월")) newdr.orderno = 0;
                    else newdr.orderno = 2;

                    if (newdr.dr == 0 && newdr.drday == 0 && newdr.cr == 0 && newdr.crday == 0) newdr.Delete();
                    else this.dsReport.holydatasum.AddholydatasumRow(newdr);
                }
            }
            this.dsReport.holydatasum.AcceptChanges();


            ////this.reportViewer1.LocalReport.ReportPath = "JobReport_\\rK5Dailyform.rdlc";
            //this.reportViewer1.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.Normal);
            //this.reportViewer1.ZoomMode = Microsoft.Reporting.WinForms.ZoomMode.Percent;
            //this.reportViewer1.RefreshReport();

            var numcell1 = new FarPoint.Win.Spread.CellType.NumberCellType();
            numcell1.DecimalPlaces = 1;
            numcell1.FixedPoint = false;
            numcell1.LeadingZero = FarPoint.Win.Spread.CellType.LeadingZero.No;
            numcell1.Separator = ",";
            numcell1.ShowSeparator = false;

            var percell1 = new FarPoint.Win.Spread.CellType.PercentCellType();
            numcell1.DecimalPlaces = 1;
            numcell1.FixedPoint = false;
            numcell1.LeadingZero = FarPoint.Win.Spread.CellType.LeadingZero.No;
            numcell1.Separator = ",";
            numcell1.ShowSeparator = false;



            //데이터표시
            var grpproc = dsReport.holydatasum.OrderBy(t => t.process).GroupBy(t => t.process);
            var row = 0;
            this.fpSpread1_Sheet1.ColumnHeaderRowCount = 2;

            var cols = new string[] { "공정", "사원명", "사번" };
            var subcols = new string[] { "이월", "발생", "사용", "잔여", "초과", "소진율(%)", "이월\n소진율\n(%)" };
            var headercol = 0;
            var catelist = new Dictionary<string, int>();
            foreach (var colname in cols)
            {
                this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = colname;
                this.fpSpread1_Sheet1.AddColumnHeaderSpanCell(0, headercol, 2, 1);
                headercol += 1;
            }

            this.fpSpread1_Sheet1.ColumnCount = 200;

            //모든카테고리를 확인하여 컬럼을 먼저 생성한다.
            var gCate = dsReport.holydatasum.OrderBy(t => t.orderno).GroupBy(t => t.cate);
            foreach (var drCate in gCate)
            {
                catelist.Add(drCate.Key, headercol);
                this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = drCate.Key;
                var grpstart = headercol;
                foreach (var colname in subcols)
                {
                    this.fpSpread1_Sheet1.ColumnHeader.Cells[1, headercol++].Value = colname;
                }
                var grpend = headercol;
                fpSpread1.ActiveSheet.AddColumnHeaderSpanCell(0, grpstart, 1, grpend - grpstart); //같은그룹명 병합
            }



            //최종합계추가
            this.fpSpread1_Sheet1.ColumnHeader.Cells[0, headercol].Value = "합계(대체/외출 제외)";
            var grpstart2 = headercol;
            foreach (var colname in subcols)
            {
                fpSpread1.ActiveSheet.ColumnCount = headercol + 1;
                this.fpSpread1_Sheet1.ColumnHeader.Cells[1, headercol++].Value = colname;
            }
            var grpend2 = headercol;
            fpSpread1.ActiveSheet.AddColumnHeaderSpanCell(0, grpstart2, 1, grpend2 - grpstart2); //같은그룹명 병합
            fpSpread1.ActiveSheet.ColumnCount = headercol;

            this.fpSpread1_Sheet1.RowCount = 1;
            foreach (var drp in grpproc)
            {
                var grpdata = drp.OrderBy(t => t.uname).GroupBy(t => t.uid);
                var grpstart = row;
                foreach (var dr in grpdata)
                {
                    var col = 0;
                    var druser = dr.First();

                    if (row % 2 == 0)
                    {
                        fpSpread1_Sheet1.Rows[row].BackColor = Color.FromArgb(80, Color.LightSkyBlue);
                    }
                    else fpSpread1_Sheet1.Rows[row].BackColor = Color.White;

                    fpSpread1_Sheet1.Cells[row, col++].Value = drp.First().process;
                    fpSpread1_Sheet1.Cells[row, col++].Value = druser.uname;
                    fpSpread1_Sheet1.Cells[row, col++].Value = druser.uid;

                    //카테고리별로 데이터를 취합하여 대상 셀에 값을기록한다.
                    var userCate = dr.GroupBy(t => t.cate);
                    var sum_발생 = 0.0;
                    var sum_사용 = 0.0;
                    var sum_잔여 = 0.0;
                    var sum_초과 = 0.0;
                    var sum_이월 = 0.0;
                    var lastcol = 0;
                    foreach (var drCate in userCate)
                    {
                        var cateName = drCate.Key;
                        var cateColumn = catelist[cateName]; //이컬럼의 시작 인덱스를 찾는다.

                        //var offset = cateColumn;
                        var 이월 = cateName.StartsWith("대체") ? drCate.Sum(t => t.iwol) : drCate.Sum(t => t.iwolday);
                        var 발생 = cateName.StartsWith("대체") ? drCate.Sum(t => t.dr) : drCate.Sum(t => t.drday);
                        var 사용 = cateName.StartsWith("대체") ? drCate.Sum(T => T.cr) : drCate.Sum(t => t.crday);
                        var 잔여 = 발생 - 사용 + 이월;
                        var 사용률 = 0.0;
                        var 사용률2 = 0.0;
                        var 초과 = 0.0;
                        if (cateName.StartsWith("이월") && 잔여 < 0)
                        {
                            잔여 = 0;
                        }
                        else
                        {
                            if (발생 + 이월 != 0) 사용률 = (사용 / (발생 + 이월)) * 100f;

                            //년차에서만 초과를 계산한다.
                            if (cateName.StartsWith("년차"))
                            {
                                //잔여가 -라면 초과분으로 한다
                                초과 = 잔여 < 0 ? -잔여 : 0;

                            }

                            if (발생 != 0) 사용률2 = ((사용 - 이월) / 발생) * 100f;

                        }

                        if (이월 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 이월;
                        else cateColumn++;
                        if (발생 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 발생;
                        else cateColumn++;
                        if (사용 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 사용;
                        else cateColumn++;
                        if (잔여 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 잔여;
                        else cateColumn++;
                        if (초과 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = 초과;
                        else cateColumn++;
                        if (사용률 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = Math.Round(사용률, 1);
                        else cateColumn++;
                        if (사용률2 != 0.0) fpSpread1_Sheet1.Cells[row, cateColumn++].Value = Math.Round(사용률2, 1);
                        else cateColumn++;


                        if (cateName.StartsWith("대체") == false && cateName.StartsWith("외출") == false)
                        {
                            sum_이월 += 이월;
                            sum_발생 += 발생;
                            sum_사용 += 사용;
                            sum_잔여 += 잔여;
                            sum_초과 += 초과;
                        }

                        if (cateColumn > lastcol) lastcol = cateColumn;
                    }

                    var sum_사용률 = Math.Round((sum_사용 / (sum_발생 + sum_이월)) * 100f, 1);
                    var sum_사용률2 = Math.Round((sum_사용 - sum_이월) / (sum_발생) * 100f, 1);


                    var offset = 0;
                    if (sum_이월 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_이월;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_발생 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_발생;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_사용 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_잔여 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_잔여;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_초과 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_초과;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_사용률 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용률;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;
                    if (sum_사용률2 != 0.0) fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = sum_사용률2;
                    else fpSpread1_Sheet1.Cells[row, headercol - subcols.Length + offset++].Value = null;

                    row += 1;
                    if (this.fpSpread1_Sheet1.RowCount < 1 + row) this.fpSpread1_Sheet1.RowCount = 1 + row;
                }
                var grpend = row;
                fpSpread1.ActiveSheet.AddSpanCell(grpstart, 0, grpend - grpstart, 1); //같은그룹명 병합
            }

            //마지막줄에는 총계를 표시한다.
            fpSpread1_Sheet1.Cells[row, 0].Value = "합계";
            fpSpread1_Sheet1.AddSpanCell(row, 0, row, 3);
            fpSpread1_Sheet1.SetFormula(row, 3, $"SUM(R1C4:R{row}C4)");

            //0번컬럼은 색상을 초기화
            for (int i = 0; i < fpSpread1_Sheet1.RowCount; i++)
                fpSpread1_Sheet1.Cells[i, 0].BackColor = Color.White;

            for (int i = 4; i <= grpend2; i++)
            {
                var colname = fpSpread1_Sheet1.Columns[i - 1].Label;
                var cellf = fpSpread1_Sheet1.Cells.Get(row, i - 1).CellType;

                if (colname.Contains("%") == false) //일반 컬럼은 합계를 ㅏㅎㄴ다
                {
                    fpSpread1_Sheet1.SetFormula(row, i - 1, $"SUM(R1C{i}:R{row}C{i})");
                }
                else
                {
                    var startindex = colname.StartsWith("소진율") ? 2 : 3;
                    //이월
                    var o이월 = fpSpread1_Sheet1.Cells[row, i - (startindex + 4)].Value;
                    //발생
                    var o발생 = fpSpread1_Sheet1.Cells[row, i - (startindex + 3)].Value;
                    //사용
                    var o사용 = fpSpread1_Sheet1.Cells[row, i - (startindex + 2)].Value;
                    //잔여
                    var o잔여 = fpSpread1_Sheet1.Cells[row, i - (startindex + 1)].Value;
                    //초과
                    var o초과 = fpSpread1_Sheet1.Cells[row, i - (startindex + 0)].Value;

                    float 이월, 발생, 사용, 잔여, 초과;
                    이월 = o이월 != null ? float.Parse(o이월.ToString()) : 0;
                    발생 = o발생 != null ? float.Parse(o발생.ToString()) : 0;
                    사용 = o사용 != null ? float.Parse(o사용.ToString()) : 0;
                    잔여 = o잔여 != null ? float.Parse(o잔여.ToString()) : 0;
                    초과 = o초과 != null ? float.Parse(o초과.ToString()) : 0;


                    var 소진율 = 0f;
                    if ((발생 + 이월) != 0) 소진율 = (사용 / (발생 + 이월)) * 100f;
                    var 소진율2 = 0f;
                    if (발생 != 0) 소진율2 = ((사용 - 이월) / 발생) * 100f;

                    if (colname.StartsWith("소진율"))
                    {

                        fpSpread1_Sheet1.SetValue(row, i - 1, 소진율);//.SetFormula(row, i - 1, $"AVERAGE(R1C{i}:R{row}C{i})");
                        fpSpread1_Sheet1.Cells[row, i - 1].CellType = numcell1;
                    }
                    else
                    {
                        fpSpread1_Sheet1.SetValue(row, i - 1, 소진율2);//    fpSpread1_Sheet1.SetFormula(row, i - 1, $"AVERAGE(R1C{i}:R{row}C{i})");
                        fpSpread1_Sheet1.Cells[row, i - 1].CellType = numcell1;
                    }

                    //var 발생 = (double)fpSpread1_Sheet1.GetValue(row, i - 1 - 4);
                    //var 사용 = (double)fpSpread1_Sheet1.GetValue(row, i - 1 - 3);
                    //var 사용률 = 0.0;
                    //if (사용 > 발생) 사용률 = 100;
                    //else if (발생 > 0) 사용률 = Math.Round((사용 / 발생) * 100f, 1);
                    //if (사용률 != 0.0)
                    //    fpSpread1_Sheet1.SetValue(row, i - 1, 사용률);
                }

                //cellf = numcell1;
            }

            fpSpread1_Sheet1.Cells[0, 0, row, grpend2 - 1].HorizontalAlignment = CellHorizontalAlignment.Center;
            fpSpread1_Sheet1.Cells[0, 0, row, grpend2 - 1].VerticalAlignment = CellVerticalAlignment.Center;

            //값이없는 컬럼은 숨김처리한다.
            string title = "";
            for (int i = 3; i < fpSpread1_Sheet1.ColumnCount; i++)
            {
                if ((i + 4) % subcols.Length == 0)
                {
                    title = fpSpread1_Sheet1.ColumnHeader.Cells[0, i].Text;
                }
                var title2 = fpSpread1_Sheet1.ColumnHeader.Cells[1, i].Text;
                if (title != "년차" && title != "합계" && title2 == "초과")
                {
                    fpSpread1_Sheet1.Columns[i].Visible = false;
                }
                else if (title != "년차" && title != "합계" && title != "대체" && title2.Contains("이월"))
                {
                    fpSpread1_Sheet1.Columns[i].Visible = false;
                }
                else fpSpread1_Sheet1.Columns[i].Visible = true;
            }
        }



        private void btSearch_Click(object sender, EventArgs e)
        {
            refrehData();
        }

        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            var sdo = DateTime.Parse(this.tbMon.Text);
            var sd = sdo.AddMonths(-1);
            tbMon.Text = sd.ToString("yyyy-MM-dd");
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            var sdo = DateTime.Parse(this.tbMon.Text);
            var sd = sdo.AddMonths(1);
            tbMon.Text = sd.ToString("yyyy-MM-dd");
        }

        private void reportViewer1_Load(object sender, EventArgs e)
        {

        }

        private void lbStt_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            var sd = new SaveFileDialog();
            sd.Filter = "excel file|*.xls";
            sd.RestoreDirectory = true;
            sd.FileName = $"휴가이력현황({tbMon.Text}).xls";
            if (sd.ShowDialog() != DialogResult.OK) return;
            this.fpSpread1.SaveExcel(sd.FileName, ExcelSaveFlags.SaveAsViewed | ExcelSaveFlags.SaveBothCustomRowAndColumnHeaders);

            var dlg = FCOMMON.Util.MsgQ("생성된 파일을 확인 할까요?");
            if (dlg != DialogResult.Yes) return;

            FCOMMON.Util.RunExplorer(sd.FileName);
        }
    }
}
