using HSUCO_Cargo_Garage_Operation_Program.CustomForm;
using MetroFramework;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Windows.Forms;

namespace HSUCO_Cargo_Garage_Operation_Program.CustomUserControl
{
    public partial class UserList : UserControl
    {
        public UserList()
        {
            InitializeComponent();
        }

        private void ApplicantList_Load(object sender, EventArgs e)
        {
            metroComboBox_SearchType.SelectedIndex = 0;
        }

        private List<UserInformation> UserType()
        {
            var userList = Database.GetUserList();
            List<UserInformation> nowUserList;

            if (metroRadioButton_UseUser.Checked)
                nowUserList = userList.Where(x => x.DateEnd >= DateTime.Now && x.PaymentStatus != EPaymentStatus.Refund).ToList();
            else if (metroRadioButton_EndUser.Checked)
                nowUserList = userList.Where(x => x.DateEnd <= DateTime.Now || x.PaymentStatus == EPaymentStatus.Refund).ToList();
            else
                nowUserList = userList;

            return nowUserList;
        }

        private List<UserInformation> PaymentType(List<UserInformation> beforUserInfromation)
        {
            List<UserInformation> userList = beforUserInfromation;
            if (metroRadioButton_StandBy.Checked)
            {
                userList = beforUserInfromation.Where(x => x.PaymentStatus == EPaymentStatus.StandBy).ToList();
            }
            else if (metroRadioButton_Use.Checked)

            {
                userList = beforUserInfromation.Where(x => x.PaymentStatus == EPaymentStatus.Use).ToList();
            }
            else if (metroRadioButton_Refund.Checked)
            {
                userList = beforUserInfromation.Where(x => x.PaymentStatus == EPaymentStatus.Refund).ToList();
            }

            return userList;
        }

        private void DataChange()
        {
            var nowUserList = UserType();
            nowUserList = PaymentType(nowUserList);
            switch (metroComboBox_SearchType.SelectedIndex)
            {
                case 0:
                    nowUserList = nowUserList
                        .Where(x => x.CargoVehicleNumber.Contains(metroTextBox_Search.Text.Trim())).ToList();

                    break;

                case 1:
                    nowUserList = nowUserList
                        .Where(x => x.PassengerVehicleNumber.Contains(metroTextBox_Search.Text.Trim())).ToList();
                    break;

                case 2:
                    nowUserList = nowUserList.Where(x => x.Name.Contains(metroTextBox_Search.Text.Trim())).ToList();
                    break;

                case 3:
                    nowUserList = nowUserList.Where(x => x.Phone.Contains(metroTextBox_Search.Text.Trim())).ToList();
                    break;

                case 4:
                    nowUserList = nowUserList.Where(x => x.Address.Contains(metroTextBox_Search.Text.Trim())).ToList();
                    break;
            }

            var dataTable = new DataTable();
            dataTable.Columns.Add("허가번호");
            dataTable.Columns.Add("허가일자");
            dataTable.Columns.Add("접수번호");
            dataTable.Columns.Add("접수일자");
            dataTable.Columns.Add("신청구분");
            dataTable.Columns.Add("성명\r\n(법인명)");
            dataTable.Columns.Add("생년월일\r\n(법인등록번호)");
            dataTable.Columns.Add("연락처");
            dataTable.Columns.Add("주소");
            dataTable.Columns.Add("주차구역");
            dataTable.Columns.Add("차량 타입");
            dataTable.Columns.Add("차량번호\r\n(화물)");
            dataTable.Columns.Add("차종\r\n(화물)");
            dataTable.Columns.Add("차량번호\r\n(승용)");
            dataTable.Columns.Add("차종\r\n(승용)");
            dataTable.Columns.Add("이용시작일");
            dataTable.Columns.Add("이용종료일");
            dataTable.Columns.Add("결재여부");
            dataTable.Columns.Add("변경사항");
            for (var i = 0; i < nowUserList.Count; i++)
            {
                StringBuilder history = new StringBuilder();
                for (int j = 0; j < nowUserList[i].HistoryInformations.Count; j++)
                {
                    history.Append(nowUserList[i].HistoryInformations[j].HistoryDate.DateTimeDatabase());
                    history.Append(" ");
                    history.AppendLine(nowUserList[i].HistoryInformations[j].HistoryCode == EHistoryCode.Extension ? "연장" : "환불");
                }
                string payment = string.Empty;
                switch (nowUserList[i].PaymentStatus)
                {
                    case EPaymentStatus.StandBy:
                        payment = "결재 대기";
                        break;

                    case EPaymentStatus.Use:
                        payment = "결재 완료";
                        break;

                    case EPaymentStatus.Refund:
                        payment = "환불";
                        break;

                    case EPaymentStatus.Delete:
                        payment = "삭제";
                        break;
                }
                string owner = string.Empty;
                switch (nowUserList[i].Owner)
                {
                    case EOwner.Individual:
                        owner = "개인";
                        break;

                    case EOwner.IndividualIntoCorporation:
                        owner = "지입";
                        break;

                    case EOwner.Corporation:
                        owner = "법인";
                        break;
                }
                string vehicleType = "";
                switch(nowUserList[i].VehicleType)
                {
                    case EVehicleType.Large_Down:
                        vehicleType = "대형(4.5톤 미만)";
                        break;
                    case EVehicleType.Large_Up:
                        vehicleType = "대형(4.5톤 이상)";
                        break;
                    case EVehicleType.Oversized_Down:
                        vehicleType = "특대형(4.5톤 미만)";
                        break;
                    case EVehicleType.Oversized_Up:
                        vehicleType = "특대형(4.5톤 이상)";
                        break;
                }
                dataTable.Rows
                    .Add(
                        nowUserList[i].No,
                        nowUserList[i].Date.DateTimeDatabase(),
                        nowUserList[i].ApplicantNo,
                        nowUserList[i].ApplicantDate.DateTimeDatabase(),
                        owner,
                        nowUserList[i].Name,
                        nowUserList[i].PersonalNumber,
                        nowUserList[i].Phone,
                        nowUserList[i].Address,
                        nowUserList[i].Area,
                        
                        vehicleType,
                        nowUserList[i].CargoVehicleNumber,
                        nowUserList[i].CargoVehicleName,
                        nowUserList[i].PassengerVehicleNumber,
                        nowUserList[i].PassengerVehicleName,
                        nowUserList[i].DateStart.ToString("yyyy-MM-dd"),
                        nowUserList[i].DateEnd.ToString("yyyy-MM-dd"),
                        payment,
                        history

                    );
            }
            dataGridView_List.DataSource = dataTable;
            dataGridView_List.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        }

        private void metroButton_Search_Click(object sender, EventArgs e)
        {
            DataChange();
        }

        private void metroButton_ExportExcel_Click(object sender, EventArgs e)
        {
            var excelWrapper = new ExcelWrapper();

            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "XLSX files (*.xlsx)|*.xlsx";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                var result = excelWrapper.WriteDataTableToExcel((DataTable)dataGridView_List.DataSource, "UserList",
                    saveFileDialog.FileName, "이용자 리스트", Environment.MachineName, DateTime.Now);
                if (result)
                {
                    MetroMessageBox.Show(this, "엑셀 파일 저장에 성공하였습니다.", "Excel Export", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    DataChange();
                }
                else
                {
                    MetroMessageBox.Show(this, "엑셀 파일 저장에 실패하였습니다.", "Excel Export", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void metroButton_Extended_Click(object sender, EventArgs e)
        {
            var selectCount = dataGridView_List.SelectedRows.Count;
            if (selectCount == 0) return;

            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();

            var status = Database.CheckPaymentStatus(no);
            if (status != EPaymentStatus.Use)
            {
                string errorMessage = string.Empty;
                switch (status)
                {
                    case EPaymentStatus.StandBy:
                        errorMessage = "아직 이용대기 중인 사용자입니다.";
                        break;

                    case EPaymentStatus.Refund:
                        errorMessage = "환불된 사용자입니다..";
                        break;

                    case EPaymentStatus.Delete:
                        errorMessage = "삭제된 사용자입니다.";
                        break;
                }
                MetroMessageBox.Show(this, errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            bool result = Database.CheckExtensionStatus(no);
            if (result)
            {
                MetroMessageBox.Show(this, "이미 연장된 사용자 입니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 연장 금액 가져오기
            EVehicleType eVehicleType = Database.GetUserListVehicleType(no);
            int amount = 0;
            if (eVehicleType == EVehicleType.Large_Down || eVehicleType == EVehicleType.Oversized_Down)
            {
                amount = Global.GlobalSettings.CargoLargeFee;
            }
            else
            {
                amount = Global.GlobalSettings.CargoOversizedFee; 
            }
            
            amount = amount * 12; // 한달치
            string cargoNumber = dataGridView_List.SelectedRows[0].Cells[9].Value.ToString();
            var message = $"선태하신 차량 {cargoNumber}을 연장하시겠습니까?\r\n연장금액 : {String.Format("{0:n0}", amount)}원";

            if (MetroMessageBox.Show(this, message, "1년 연장", MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Information) == DialogResult.OK)
            {
                bool updtaeResult = Database.UpdateExtended(no, amount);
                if (updtaeResult)
                {
                    MetroMessageBox.Show(this, "연장처리 완료하였습니다.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MetroMessageBox.Show(this, "연장에 실패하였습니다.", "Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
                }

                DataChange();
            }
        }

        private void metroButton_Refund_Click(object sender, EventArgs e)
        {
            var count = dataGridView_List.SelectedRows.Count;
            if (count == 0) return;
            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();
            GetRefundInformation getRefundInformation = Database.GetRefundData(no);
            if (getRefundInformation.PaymentStatus == EPaymentStatus.Refund)
            {
                MetroMessageBox.Show(this, "이미 환불된 사용자 입니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Refund refund = new Refund(getRefundInformation);
            refund.ShowDialog();
            if (refund.DialogResult != DialogResult.OK)
            {
                return;
            }
            DateTime refundDateTime = refund.RefundDateTime;

            int totalAmount = 0;

            if (getRefundInformation.DateEnd < refundDateTime)
            {
                MetroMessageBox.Show(this, "이용종료일이 환불일 보다 이전입니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 연장여부
            // 이용 전 이면
            if (getRefundInformation.DateStart > refundDateTime)
            {
                refundDateTime = getRefundInformation.DateStart;

                totalAmount += getRefundInformation.BaseFee;
                if (getRefundInformation.ExtensionStatus)
                {
                    totalAmount += getRefundInformation.ExtensionFee;
                }
            }
            else if (getRefundInformation.ExtensionStatus)
            {
                //연장일 보다 환불일이 늦는경우(연장에 부분만 일자 계산후 정산)
                if (getRefundInformation.ExtensionStart < refundDateTime)
                {
                    // 연장 시작 부와 비교
                    ProgressDays progressDays = Extends.GetProgressDays(refundDateTime, getRefundInformation.DateEnd);
                    int totalMonth = Extends.GetProgressMonth(getRefundInformation.ExtensionStart.Year, getRefundInformation.ExtensionStart.Month, getRefundInformation.DateEnd.Year, getRefundInformation.DateEnd.Month);
                    int monthAmount = getRefundInformation.ExtensionFee / totalMonth;
                    int leftAmount = progressDays.Month * monthAmount;
                    if (progressDays.StartDay != 0)
                    {
                        leftAmount += (monthAmount / progressDays.StartTotalDay) * (progressDays.StartTotalDay - progressDays.StartDay);
                    }
                    if (leftAmount > 0)
                    {
                        leftAmount = leftAmount / 10 * 10;
                    }
                    totalAmount += leftAmount;
                    // 연장부분만 계산
                }
                else
                {
                    DateTime endDate = getRefundInformation.ExtensionStart.AddDays(-1);
                    ProgressDays progressDays = Extends.GetProgressDays(refundDateTime, endDate);
                    int totalMonth = Extends.GetProgressMonth(getRefundInformation.DateStart.Year, getRefundInformation.DateStart.Month, endDate.Year, endDate.Month);
                    int monthAmount = getRefundInformation.BaseFee / totalMonth;
                    int leftAmount = progressDays.Month * monthAmount;
                    if (progressDays.StartDay != 0)
                    {
                        leftAmount += (monthAmount / progressDays.StartTotalDay) * (progressDays.StartTotalDay - progressDays.StartDay);
                    }
                    if (leftAmount > 0)
                    {
                        leftAmount = leftAmount / 10 * 10;
                    }
                    totalAmount += leftAmount;
                    // 연장 부분 전체
                    totalAmount += getRefundInformation.ExtensionFee;
                }
                // 연장한 경우
            }
            else
            {
                // 연장안한경우
                ProgressDays progressDays = Extends.GetProgressDays(refundDateTime, getRefundInformation.DateEnd);
                int totalMonth = Extends.GetProgressMonth(getRefundInformation.DateStart.Year, getRefundInformation.DateStart.Month, getRefundInformation.DateEnd.Year, getRefundInformation.DateEnd.Month);
                int monthAmount = getRefundInformation.BaseFee / totalMonth;
                int leftAmount = progressDays.Month * monthAmount;
                if (progressDays.StartDay != 0)
                {
                    leftAmount += (monthAmount / progressDays.StartTotalDay) * (progressDays.StartTotalDay - progressDays.StartDay);
                }
                if (leftAmount > 0)
                {
                    leftAmount = leftAmount / 10 * 10;
                }
                totalAmount += leftAmount;
            }

            DialogResult dialogResult = MetroMessageBox.Show(this, $"환불 처리 하시겟습니까?\r\n     환불 금액 : {String.Format("{0:n0}", totalAmount)}원", "환불", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);

            if (dialogResult == DialogResult.OK)
            {
                bool result = Database.SetRefund(no, refundDateTime, totalAmount);
                if (result)
                {
                    MetroMessageBox.Show(this, "환불처리가 완료되었습니다.", "환불", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    DataChange();
                }
                else
                {
                    MetroMessageBox.Show(this, "환불처리가 실패하였습니다.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void metroButton_Certificate_Click(object sender, EventArgs e)
        {
            DateTime nowDateTime = DateTime.Now;
            var count = dataGridView_List.SelectedRows.Count;
            if (count == 0)
            {
                MetroMessageBox.Show(this, "선택된 이용자가 없습니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();
            
            var result = MetroMessageBox.Show(this, "발급 하시겠습니까?", "증명서 발급", MessageBoxButtons.YesNo,
                MessageBoxIcon.Question);
            if (result == DialogResult.No) return;

            
            CertificateInformation certificateInformation = Database.GetUserCertificate(no);
            Promotion promotion = new Promotion("증명서 인증 기간", "증명 시작일", "증명 종료일");
            DialogResult promotionDialogResult = promotion.ShowDialog();
            if (promotionDialogResult != DialogResult.OK)
            {
                return;
            }
            if (promotion.StartDate < certificateInformation.StartDate)
            {
                MetroMessageBox.Show(this, "인증 시작일이 이용일 보다 먼저 일수 없습니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (promotion.EndDate > certificateInformation.EndDate)
            {
                MetroMessageBox.Show(this, "인증 종료일이 이용일 보다 나중일수 없습니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            certificateInformation.IssueDate = nowDateTime;

            int lastNo = Database.GetLastCertificate(nowDateTime.Year);
            lastNo++;
            certificateInformation.IssueNumber = nowDateTime.Year.ToString() + "-C" + lastNo.ToString();

            SetCertificateInformation setCertificateInformation = new SetCertificateInformation();
            setCertificateInformation.No = certificateInformation.IssueNumber;
            setCertificateInformation.UserNo = no;
            setCertificateInformation.IssueDate = certificateInformation.IssueDate;
            setCertificateInformation.StartDate = promotion.StartDate;
            setCertificateInformation.EndDate = promotion.EndDate;
            setCertificateInformation.Amount = certificateInformation.Amount;

            // 증명서 발급 요금 계산
            EVehicleType eVehicleType = Database.GetUserListVehicleType(setCertificateInformation.UserNo);
            int payBase = 0;
            if (eVehicleType == EVehicleType.Large_Down || eVehicleType == EVehicleType.Large_Up)
            {
                payBase = Global.GlobalSettings.CargoLargeCertificateFee;
            }
            else
            {
                payBase = Global.GlobalSettings.CargoOversizedCertificateFee;
            }
            int month = Extends.GetProgressDays(promotion.StartDate, promotion.EndDate).Month;
            int pay = month * payBase;

            SetProceedsInfo setProceedsInfo = new SetProceedsInfo();
            setProceedsInfo.No = setCertificateInformation.UserNo;
            setProceedsInfo.Date = nowDateTime;
            setProceedsInfo.Type = EProceedsType.Certificate;
            setProceedsInfo.Amount = pay;

            string amount = string.Format("{0:N0} 원", setProceedsInfo.Amount);
            var dialogResult = MetroMessageBox.Show(this, $"증명서 발급요금이 {amount} 발생했습니다. 발급하시겠습니까?", "Question", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.OK)
            {
                Database.SetCertificate(setCertificateInformation);
                Database.SetProceeds(setProceedsInfo);

                var print = new PrintCertificate(new List<CertificateInformation>() { certificateInformation }, Global.GlobalSettings.GarageName);
                print.Print();
            }
        }

        private void metroButton_UpdateUserData_Click(object sender, EventArgs e)
        {
            var selectCount = dataGridView_List.SelectedRows.Count;
            if (selectCount == 0) return;
            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();

            UpdateUserInformation updateUserInformation = Database.GetUserData(EUserInformationType.UserList, no);
            UpdateUserData updateUserData = new UpdateUserData(updateUserInformation);
            DialogResult dialogResult = updateUserData.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                DataChange();
            }
        }

        private void metroButton_PaymentOk_Click(object sender, EventArgs e)
        {
            var selectCount = dataGridView_List.SelectedRows.Count;
            if (selectCount == 0) return;
            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();
            var status = Database.CheckPaymentStatus(no);
            if (status != EPaymentStatus.StandBy)
            {
                MetroMessageBox.Show(this, "현재 사용자는 결재 완료로 전환할수 없는 사용자 입니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            GetPaymentBaseInformation getPaymentBaseInformation = Database.GetPaymentBase(no);
            int payBase = getPaymentBaseInformation.VehicleType == EVehicleType.Large_Down || getPaymentBaseInformation.VehicleType == EVehicleType.Oversized_Down ? Global.GlobalSettings.CargoLargeFee : Global.GlobalSettings.CargoOversizedFee;
            int pay = getPaymentBaseInformation.Month * payBase;
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("선택하신 사용자의 수납을 확인하시겠습니까 ?");
            sb.AppendLine($"이용개월 : {getPaymentBaseInformation.Month}월");
            sb.AppendLine($"이용금액(월) : {payBase}원");
            sb.AppendLine($"총 이용금액 : {pay}원");

            var result = MetroMessageBox.Show(this, sb.ToString(), "Information", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (result == DialogResult.Yes)
            {
                Database.AcceptUser(no, pay);
                MetroMessageBox.Show(this, "완료되었습니다.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                DataChange();
            }
        }

        private void metroButton_DeleteStandBy_Click(object sender, EventArgs e)
        {
            var selectCount = dataGridView_List.SelectedRows.Count;
            if (selectCount == 0) return;
            string no = dataGridView_List.SelectedRows[0].Cells[0].Value.ToString();
            var status = Database.CheckPaymentStatus(no);
            if (status == EPaymentStatus.Delete)
            {
                DialogResult dialogResult =  MetroMessageBox.Show(this, "해당 사용자는 이미 삭제된 사용자입니다. 복구 하시겠습니까?", "Information", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                if(dialogResult== DialogResult.No )
                {
                    return;
                }
                bool result = Database.DeleteUserUndo(no);
                if(result)
                {
                    MetroMessageBox.Show(this, "성공적으로 복구 하였습니다..", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    DataChange();
                }
                else
                {
                    MetroMessageBox.Show(this, "이미 해당자리에 다른 사용자가 있습니다..", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return;

            }

            else if (status != EPaymentStatus.StandBy)
            {
                MetroMessageBox.Show(this, "현재 사용자는 삭제처리할수 없는 사용자 입니다.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            
            
            Database.DeleteUser(no);
            MetroMessageBox.Show(this, "해당 사용자를 제거 완료했습니다.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            DataChange();
        }
    }
}