using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JobReportMailService
{
    public partial class fJobReportDay : fChildBase
    {

        public fJobReportDay()
        {
            InitializeComponent();
        }

        private void fJobReportDay_Load(object sender, EventArgs e)
        {
            task = Task.Run(() =>
            {
                while(taskrun)
                {
                    if (taskwait)
                    {
                        task.Wait(1000);
                        continue;
                    }

                    var ts = DateTime.Now - LastUpdateTime;
                    if (ts.TotalMinutes <= 15)
                    {
                        if ((DateTime.Now - ConsoleTime).TotalHours >= 1.0)
                        {
                            addmsg("15분 미만이라 동작하지 않습니다");
                            ConsoleTime = DateTime.Now;
                        }
                    }
                    else if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday ||
                    DateTime.Now.DayOfWeek == DayOfWeek.Sunday ||
                    DateTime.Now.DayOfWeek == DayOfWeek.Monday)
                    {
                        //토,일요일에는 동작하지 않는다
                        if ((DateTime.Now - ConsoleTime).TotalHours >= 1.0)
                        {
                            addmsg("토/일/월에는 동작하지 않습니다");
                            ConsoleTime = DateTime.Now;
                        }
                    }
                    else if (DateTime.Now.Hour < 9)
                    {
                        if ((DateTime.Now - ConsoleTime).TotalHours >= 1.0)
                        {
                            addmsg("9시 이전에는 동작하지 않습니다");
                            ConsoleTime = DateTime.Now;
                        }
                    }
                    else
                    {
                        LastUpdateTime = DateTime.Now;
                        try
                        {
                            RunData();
                        }
                        catch (Exception ex)
                        {
                            addmsg(ex.Message);
                            task.Wait(5000);
                        }
                    }
                    Task.Delay(Delaytime).Wait();
                }
               
            });
            timer1.Start();
        }

        void RunData()
        {
            addmsg("업무일지 미 작성자 추출 작업을 시작 합니다");


            var db = new EEEntities();

            //메일양식이 지정되어있는지 체크
            var MailJD = db.MailForm.Where(t => t.gcode == Pub.vGcode & t.cate == "JD").FirstOrDefault();
            //var MailJW = db.MailForm.Where(t => t.gcode == vGcode & t.cate == "JW").FirstOrDefault();

            if (MailJD == null)
            {
                //토,일요일에는 동작하지 않는다
                addmsg("업무일지 미작성 메일 양식이 입력되지 않았습니다");
                return;
            }

            //기준일자는 오늘부터 -15일이다
            var sd = DateTime.Now.AddDays(-15);
            var ed = DateTime.Now;
            var str_sd = sd.ToShortDateString();
            var str_ed = ed.ToShortDateString();
            var str_dt = DateTime.Now.ToShortDateString();

            //대상 사용자 목록을 추출한다
            db = new EEEntities();
            var users = db.vJobReportForUser.Where(t => t.gcode == Pub.vGcode).GroupBy(t => t.id);
            Dictionary<string, string> uids = new Dictionary<string, string>();
            foreach (var user in users)
            {
                //해당 사용자의 오늘 날짜로 등록된 자동 데이터가 있다면 대상에 넣지 않는다
                var userinfo = user.FirstOrDefault();

                //퇴사자 확인
                db = new EEEntities();
                var userdata = db.vGroupUser.Where(t => t.id == userinfo.id).FirstOrDefault();
                if (userdata != null && string.IsNullOrEmpty(userdata.outdate) == false) continue;

                db = new EEEntities();
                var Exists = db.MailData.Where(t => t.gcode == Pub.vGcode && t.wuid == userinfo.id && t.pdate == str_dt && t.cate == "JD").Any();
                if (Exists == false) uids.Add(userinfo.id, userinfo.name);   //자동생성된 자료가 없는 경우에만 처리한다
            }


            addmsg($"{uids.Count} 명의 전체 사용자가 확인 되었습니다");

            //먼저 날짜목록을 가져온다
            db = new EEEntities();
            var lstDate = db.JobReport
                .Where(t => t.gcode == Pub.vGcode && t.pdate.CompareTo(str_sd) >= 0 && t.pdate.CompareTo(str_ed) < 0)
                .OrderBy(t => t.pdate)
                .GroupBy(t => t.pdate).ToList();

            //날짜대로 루프를 돈다
            List<DateTime> days = new List<DateTime>();
            foreach (var dateitem in lstDate)
            {
                var jobdata = dateitem.FirstOrDefault();
                var dt = DateTime.Parse(jobdata.pdate);
                if (dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday) continue;

                //이 날짜가 휴일인지 체크한다.
                db = new EEEntities();
                var Holyinfo = db.HolidayLIst.Where(t => t.pdate == jobdata.package).FirstOrDefault();
                if (Holyinfo != null && Holyinfo.free != null && (bool)(Holyinfo.free)) continue;

                //이날짜에는 8시간을 근무 해야 한다
                days.Add(DateTime.Parse(jobdata.pdate));
            }
            addmsg($"{days.Count} 건의 일자가 확인 되었습니다(기간:{str_sd}~{str_ed}");

            //사용자 목록과 날짜 목록을 모두 수집했다
            List<ReportUserData> totWarnList = new List<ReportUserData>();
            foreach (var uid in uids)
            {
                if(uid.Key == "320854")
                    Console.WriteLine("테스트");

                //이사용자의 날짜별 근무시간을 확인한다.
                db = new EEEntities();
                var UserDatas = db.vJobReportForUser.Where(t => t.gcode == Pub.vGcode && t.id == uid.Key && t.pdate.CompareTo(str_sd) >= 0 && t.pdate.CompareTo(str_ed) < 0).ToList();

                Dictionary<DateTime, double?> WarnList = new Dictionary<DateTime, double?>();
                foreach (var dt in days.OrderBy(t => t))
                {
                    var dtstr = dt.ToShortDateString();
                    var userdata = UserDatas.Where(t => t.pdate == dtstr); //해당날짜의 데이터를 확인한다.
                    var hrs = 0.0;
                    if (userdata.Any()) hrs = (double)userdata.Sum(t => t.hrs);

                    //자료를 입력하지 않았거나, 입력시간이 8시간 미만이면 경고한다
                    if (hrs < 8.0)
                    {
                        WarnList.Add(dt, hrs);
                        totWarnList.Add(new ReportUserData { date = dt, hrs = hrs, uid = uid.Key, uname = uid.Value }); //전체알림시에 사용하는 목록
                    }
                }

                if (WarnList.Count > 0)
                {
                    addmsg($"{uid.Value}({uid.Key}) 의 경고 일수는 {WarnList.Count} 건 입니다");

                    db = new EEEntities();
                    var userinfo = db.vGroupUser.Where(t => t.id == uid.Key).FirstOrDefault();
                    if (userinfo == null)
                    {
                        addmsg($"{uid.Value}({uid.Key}) 의 사용자 정보를 확인 할 수 없습니다");
                    }
                    else if (string.IsNullOrEmpty(userinfo.email))
                    {
                        addmsg($"{uid.Value}({uid.Key}) 의 메일 정보가 존재하지 않습니다");
                    }
                    else
                    {
                        //일별경고(월요일제외)

                        if (DateTime.Now.DayOfWeek != DayOfWeek.Monday && MailJD != null)
                        {
                            var mail_subject = MailJD.subject.Replace("{담당자}", userinfo.name).Replace("{사번}", userinfo.id);
                            var mail_to = MailJD.tolist.Replace("{담당자}", userinfo.email);
                            var mail_cc = string.Empty; //
                            if (MailJD.cc != null) mail_cc = MailJD.cc.Replace("{담당자}", userinfo.email);
                            var mail_bcc = string.Empty;
                            if (MailJD.bcc != null) mail_bcc = MailJD.bcc.Replace("{담당자}", userinfo.email);
                            var mail_body = MailJD.body.Replace("{담당자}", userinfo.name);
                            mail_body = mail_body.Replace("{사번}", userinfo.id);

                            //메일본문을 생성해서 진행해야함
                            var mail_content = "<p>일자별 정보</p>";
                            mail_content += $"<br/>조회기간 : {str_sd}~{str_ed}";
                            mail_content += "<br/><table border='1' cellspacing='1' cellpadding='1'><tr><td>날짜</td><td>요일</td><td>시간</td></tr>";
                            foreach (var warnitem in WarnList)
                            {
                                mail_content += $"<tr><td>{warnitem.Key.ToShortDateString()}</td><td>{warnitem.Key.DayOfWeek.ToString()}</td><td>{warnitem.Value.ToString()}</td></tr>";
                            }
                            mail_content += "</table>";

                            //메일데이터를 생성한다.
                            //mail_to = "chikyun.kim@amkor.co.kr";
                            //mail_bcc = string.Empty;
                            //mail_cc = string.Empty;

                            mail_to = Pub.MailSort(mail_to, MailJD.exceptmail);
                            if (string.IsNullOrEmpty(mail_to) == false)
                            {
                                db = new EEEntities();
                                db.MailData.Add(new MailData
                                {
                                    gcode = Pub.vGcode,
                                    cate = "JD",
                                    subject = mail_subject,
                                    fromlist = userinfo.email,
                                    tolist = Pub.MailSort(mail_to, MailJD.exceptmail),
                                    bcc = mail_bcc,
                                    cc = Pub.MailSort(mail_cc, MailJD.exceptmailcc),
                                    pdate = DateTime.Now.ToShortDateString(),
                                    body = mail_body.Replace("{내용}", mail_content),
                                    wuid = userinfo.id,
                                    wdate = DateTime.Now,
                                });
                                db.SaveChanges();
                                addmsg($"{userinfo.name}({userinfo.email}) 메일 전송 완료(day)");
                                System.Threading.Thread.Sleep(10000);
                            }
                            else
                            {
                                addmsg("받는사람이 소거되어 메일을 생성하지 않습니다");
                            }
                        }
                    }
                    System.Threading.Thread.Sleep(3000);
                }
                else
                {
                    addmsg($"{uid.Value}({uid.Key}) 미 작성 일자가 없습니다");
                }

            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            taskwait = !taskwait;
            if (taskwait == false)
                LastUpdateTime = DateTime.Now.AddHours(-1);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (task != null)
            {
                if (task.IsCompleted) this.toolStripButton1.Text = "완료";
                else if (task.IsCanceled) this.toolStripButton1.Text = "취소";
                else if (taskwait) this.toolStripButton1.Text = "대기상태";
                else this.toolStripButton1.Text = "가동중";
                this.toolStripButton1.Enabled = true;
            }
            else
            {
                this.toolStripButton1.Text = "사용불가";
                this.toolStripButton1.Enabled = false;
            }
            
        }
    }
}
