
using Shared;
using Shared.DTOs;
using SixLabors.ImageSharp.Formats;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;

namespace Back.Services
{
    public class servReport
    {
         string[] ones = { "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه" };
         string[] tens = { "", "ده", "بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود" };
         string[] teens = { "ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده" };
         string[] hundreds = { "", "صد", "دویست", "سیصد", "چهارصد", "پانصد", "ششصد", "هفتصد", "هشتصد", "نهصد" };

        // تابع برای تبدیل اعداد به فارسی
         static string ConvertToPersian(string number)
        {
            // دیکشنری برای تبدیل اعداد انگلیسی به فارسی
            var persianDigits = new[] { '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹' };

            // تبدیل هر رقم انگلیسی به فارسی
            char[] numberArray = number.ToCharArray();
            for (int i = 0; i < numberArray.Length; i++)
            {
                if (Char.IsDigit(numberArray[i]))
                {
                    int digit = numberArray[i] - '0'; // پیدا کردن معادل عددی
                    numberArray[i] = persianDigits[digit]; // تبدیل به معادل فارسی
                }
            }

            return new string(numberArray);
        }
        // تابع برای جدا کردن سه‌رقمی
         static string FormatWithCommas(decimal number)
        {
            return number.ToString("#,0", CultureInfo.InvariantCulture);
        }
         string ConvertToWords(decimal number)
        {
            if (number == 0)
                return "صفر";

            if (number < 0)
                return "منفی " + ConvertToWords(-number);

            string words = "";

            long integerPart = (long)Math.Floor(number);
            int fractionPart = (int)((number - integerPart) * 100);

            if (integerPart / 1000000000 > 0)
            {
                words += ConvertToWords(integerPart / 1000000000) + " میلیارد ";
                integerPart %= 1000000000;
            }

            if (integerPart / 1000000 > 0)
            {
                words += ConvertToWords(integerPart / 1000000) + " میلیون ";
                integerPart %= 1000000;
            }

            if (integerPart / 1000 > 0)
            {
                words += ConvertToWords(integerPart / 1000) + " هزار ";
                integerPart %= 1000;
            }

            if (integerPart / 100 > 0)
            {
                words += hundreds[integerPart / 100] + " ";
                integerPart %= 100;
            }

            if (integerPart > 0)
            {
                if (words != "")
                    words += "و ";

                if (integerPart < 10)
                    words += ones[integerPart];
                else if (integerPart < 20)
                    words += teens[integerPart - 10];
                else
                {
                    words += tens[integerPart / 10];
                    if ((integerPart % 10) > 0)
                        words += " و " + ones[integerPart % 10];
                }
            }

            if (fractionPart > 0)
            {
                if (words != "")
                    words += " و ";
                words += ConvertToWords(fractionPart) + " صدم";
            }

            return words;
        }
        public async Task<string> CreateImage(InvoiceDTO invoice, string logoBase64="", string companyName="")
        {
            if (string.IsNullOrEmpty(logoBase64))
                logoBase64 = "[encoded data, 52628 characters]";
            // مشخص کردن اندازه تصویر
            int width = 900;
            int height = 200 + (invoice.items.Count * 30) + 50; // افزایش ارتفاع برای فضای بیشتر در پایین صفحه

            // ایجاد تصویر جدید
            Bitmap bitmap = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(bitmap);

            // تنظیمات اولیه گرافیک
            graphics.Clear(Color.White); // زمینه سفید
            Font font = new Font("B Nazanin", 12); // استفاده از فونت فارسی
            Font hfont = new Font("B Nazanin", 12, FontStyle.Bold); // for header
            SolidBrush brush = new SolidBrush(Color.Black);
            Pen pen = new Pen(Color.Black, 1);  // قلم برای رسم خطوط جدول

            // تنظیمات عنوان
            string titleText = $"صورتحساب  {invoice.invoiceType.GetEnumDisplayName()}";
            Font titleFont = new Font("B Nazanin", 18, FontStyle.Bold);  // فونت بزرگ‌تر و بولد
            SizeF titleTextSize = graphics.MeasureString(titleText, titleFont);
            int titleTextX = (width - (int)titleTextSize.Width) / 2;  // وسط صفحه
            int titleTextY = 20;  // موقعیت عمودی (بالای صفحه)

            graphics.DrawString(titleText, titleFont, Brushes.DarkBlue, titleTextX, titleTextY);

            // بارگذاری لوگو از رشته Base64
            byte[] logoBytes = Convert.FromBase64String(logoBase64);
            using (MemoryStream ms = new MemoryStream(logoBytes))
            {
                Image logo = Image.FromStream(ms);

                int logoWidth = 50;  // عرض لوگو
                int logoHeight = 50;  // ارتفاع لوگو
                int logoX = 60;  // موقعیت افقی لوگو (سمت چپ)
                int logoY = 70;  // موقعیت عمودی لوگو (بعد از عنوان)

                // رسم لوگو در سمت چپ بالای صفحه
                graphics.DrawImage(logo, logoX, logoY, logoWidth, logoHeight);

                // نوشتن متن "شرکت فرزان" در سمت راست بالای صفحه
                //string companyName = "شرکت فرزان سیستم مانا";
                Font companyFont = new Font("B Nazanin", 14, FontStyle.Bold);  // فونت برای نام شرکت
                SizeF textSize = graphics.MeasureString(companyName, companyFont);
                int textX = width - (int)textSize.Width - 20;  // موقعیت افقی متن (سمت راست)
                int textY = logoY;  // موقعیت عمودی متن (همسطح با لوگو)

                graphics.DrawString(companyName, companyFont, Brushes.DarkGreen, textX, textY);

                // نوشتن متن تاریخ در سمت چپ
                string dateText = "تاریخ: " + ConvertToPersian(invoice.InvoiceDate);
                Font dateFont = new Font("B Nazanin", 12);  // فونت برای تاریخ
                SizeF dateTextSize = graphics.MeasureString(dateText, dateFont);
                int dateTextX = 20;  // موقعیت افقی تاریخ (سمت چپ)
                int dateTextY = logoY + logoHeight + 10;  // فاصله بیشتر از "شرکت فرزان"

                graphics.DrawString(dateText, dateFont, Brushes.Black, dateTextX, dateTextY);

                // نوشتن متن "خریدار: مهدی ربیع نژاد" در پایین سمت راست
                string buyerText = $"خریدار: {invoice.CustomerName}";
                Font buyerFont = new Font("B Nazanin", 12);  // فونت برای نام خریدار
                SizeF buyerTextSize = graphics.MeasureString(buyerText, buyerFont);
                int buyerTextX = width - (int)buyerTextSize.Width - 20;  // موقعیت افقی (سمت راست)

                // کاهش فاصله از "شرکت فرزان" برای "خریدار"
                int buyerTextY = dateTextY - 30;  // فاصله کمتر از نام شرکت

                graphics.DrawString(buyerText, buyerFont, Brushes.Black, buyerTextX, buyerTextY);
            }

            // تنظیم موقعیت شروع برای نوشتن جدول
            int x = 10;
            int y = 170;  // کاهش فاصله با تغییر مقدار y (در اینجا 200 به جای 240)
            int rowHeight = 30;

            // تغییر عرض ستون‌ها برای تنظیم فاصله
            int columnWidth1 = 240; // ستون شناسه کالا
            int columnWidth2 = 50; // ستون واحد
            int columnWidth3 = 70; // ستون تعداد
            int columnWidth4 = 100; // ستون مبلغ واحد
            int columnWidth5 = 50; // ستون نرخ مالیات
            int columnWidth6 = 120; // ستون مبلغ مالیات
            int columnWidth7 = 100; // ستون تخفیف
            int columnWidth8 = 130; // ستون مبلغ کل

            // رسم هدر جدول با رنگ پس‌زمینه و تغییر رنگ متن
            graphics.FillRectangle(Brushes.LightSteelBlue, x, y, width - 15, rowHeight);  // رنگ پس‌زمینه هدر
            graphics.DrawString("کالا", hfont, Brushes.White, x + (columnWidth1 - graphics.MeasureString("کالا", font).Width) / 2, y + 5);
            graphics.DrawString("واحد", hfont, Brushes.White, x + columnWidth1 + (columnWidth2 - graphics.MeasureString("واحد", font).Width) / 2, y + 5);
            graphics.DrawString("تعداد", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + (columnWidth3 - graphics.MeasureString("تعداد", font).Width) / 2, y + 5);
            graphics.DrawString("مبلغ واحد", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + columnWidth3 + (columnWidth4 - graphics.MeasureString("مبلغ واحد", font).Width) / 2, y + 5);
            graphics.DrawString("نرخ مالیات", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + (columnWidth5 - graphics.MeasureString("نرخ مالیات", font).Width) / 2, y + 5);
            graphics.DrawString("مبلغ مالیات", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + (columnWidth6 - graphics.MeasureString("مبلغ مالیات", font).Width) / 2, y + 5);
            graphics.DrawString("تخفیف", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + columnWidth6 + (columnWidth7 - graphics.MeasureString("تخفیف", font).Width) / 2, y + 5);
            graphics.DrawString("مبلغ کل", hfont, Brushes.White, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + columnWidth6 + columnWidth7 + (columnWidth8 - graphics.MeasureString("مبلغ کل", font).Width) / 2, y + 5);
            y += rowHeight;

            // رسم خطوط افقی
            graphics.DrawLine(pen, x, y, width - 10, y);

            // نوشتن داده‌ها در جدول
            foreach (var product in invoice.items)
            {
                graphics.DrawString(product.sstt, font, brush, x + (columnWidth1 - graphics.MeasureString(product.sstt, font).Width) / 2, y + 5);
                graphics.DrawString(product.mu, font, brush, x + columnWidth1 + (columnWidth2 - graphics.MeasureString(product.am.ToString().Split('٫')[0], font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(product.am.ToString().Split('٫')[0]), font, brush, x + columnWidth1 + columnWidth2 + (columnWidth3 - graphics.MeasureString(ConvertToPersian(product.am.ToString().Split('٫')[0].ToString()), font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(FormatWithCommas(product.fee)), font, brush, x + columnWidth1 + columnWidth2 + columnWidth3 + (columnWidth4 - graphics.MeasureString(ConvertToPersian(FormatWithCommas(product.fee)), font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(FormatWithCommas(product.vra.GetValueOrDefault())), font, brush, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + (columnWidth5 - graphics.MeasureString(ConvertToPersian(FormatWithCommas(product.vra.GetValueOrDefault())), font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(FormatWithCommas(product.vam.GetValueOrDefault())), font, brush, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + (columnWidth6 - graphics.MeasureString(ConvertToPersian(FormatWithCommas(product.vam.GetValueOrDefault())), font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(FormatWithCommas(product.dis.GetValueOrDefault())), font, brush, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + columnWidth6 + (columnWidth7 - graphics.MeasureString(ConvertToPersian(FormatWithCommas(product.dis.GetValueOrDefault())), font).Width) / 2, y + 5);
                graphics.DrawString(ConvertToPersian(FormatWithCommas(product.tsstam.GetValueOrDefault())), font, brush, x + columnWidth1 + columnWidth2 + columnWidth3 + columnWidth4 + columnWidth5 + columnWidth6 + columnWidth7 + (columnWidth8 - graphics.MeasureString(ConvertToPersian(FormatWithCommas(product.tsstam.GetValueOrDefault())), font).Width) / 2, y + 5);
                y += rowHeight;

                // رسم خطوط افقی برای هر ردیف
                graphics.DrawLine(pen, x, y, width - 10, y);
            }
            //-----------

            // نوشتن متن "مبلع نهایی" در سمت راست بالای صفحه
            string totalfactor = $"مبلع نهایی: {ConvertToWords(invoice.tbill.GetValueOrDefault())} ريال";
            Font totalFont = new Font("B Nazanin", 12, FontStyle.Bold);  // فونت برای نام شرکت
            SizeF totaltextSize = graphics.MeasureString(totalfactor, totalFont);
            int totalX = width - (int)totaltextSize.Width - 20;
            int totalY = y;  // موقعیت عمودی متن (همسطح با لوگو)
            graphics.DrawString(totalfactor, totalFont, Brushes.Black, totalX, totalY);

            // اضافه کردن توضیحات پایین صفحه در وسط
            string descriptionText = $"توضیحات: {(string.IsNullOrEmpty(invoice.Des) ? "سامانه مودیران" :invoice.Des)}";
            Font descriptionFont = new Font("B Nazanin", 12);
            SizeF descriptionTextSize = graphics.MeasureString(descriptionText, descriptionFont);
            int descriptionX = (width - (int)descriptionTextSize.Width) / 2;
            int descriptionY = y + 20; // فاصله از جدول

            graphics.DrawString(descriptionText, descriptionFont, Brushes.DarkRed, descriptionX, descriptionY);

            string ret = "";
            using (MemoryStream ms = new MemoryStream())
            {
                // Save the Bitmap to the memory stream
                bitmap.Save(ms, ImageFormat.Png);

                // Convert the memory stream to a byte array
                byte[] imageBytes = ms.ToArray();

                // Convert the byte array to a Base64 string
                ret= Convert.ToBase64String(imageBytes);
            }


            // ذخیره تصویر به فرمت PNG
           // bitmap.Save(filePath, ImageFormat.Png);

            // آزادسازی منابع
            graphics.Dispose();
            bitmap.Dispose();

            return ret;
        }


    }
}
