using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PTMedicalInsurance.Common
{
    public static class Base64StreamingEncoder
    {
        /// <summary>
        /// 将文件以流式方式转换为 Base64 字符串（适用于大文件）
        /// </summary>
        /// <param name="inputFilePath">输入 ZIP 文件路径</param>
        /// <param name="outputWriter">输出目标（如 StreamWriter、StringWriter 或网络流）</param>
        /// <param name="chunkSize">每次读取的字节数（建议 3 的倍数，如 36864）</param>
        public static void ConvertToBase64Stream(string inputFilePath, TextWriter outputWriter, int chunkSize = 36864)
        {
            // 确保 chunkSize 是 3 的倍数，避免 Base64 编码时出现填充混乱（可选优化）
            if (chunkSize % 3 != 0)
                throw new ArgumentException("chunkSize 最好是 3 的倍数，以提高 Base64 效率。");

            byte[] buffer = new byte[chunkSize];
            int bytesRead;

            // 保留未完全编码的字节（用于跨块对齐）
            var leftoverBuffer = new byte[2]; // Base64 每 3 字节一组，最多余 2 字节
            int leftoverCount = 0;

            using (var fileStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: false))
            {
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    // 当前块 + 上次剩余字节，组成完整处理单元
                    int totalAvailable = leftoverCount + bytesRead;
                    var processBuffer = new byte[totalAvailable];
                    Array.Copy(leftoverBuffer, 0, processBuffer, 0, leftoverCount);
                    Array.Copy(buffer, 0, processBuffer, leftoverCount, bytesRead);

                    // 计算可以完整编码的字节数（必须是 3 的倍数）
                    int fullGroups = (totalAvailable / 3) * 3;
                    int remaining = totalAvailable - fullGroups;

                    // 编码完整组
                    string encoded = Convert.ToBase64String(processBuffer, 0, fullGroups);
                    outputWriter.Write(encoded);

                    // 保存剩余字节（用于下一次）
                    Array.Clear(leftoverBuffer, 0, leftoverBuffer.Length);
                    Array.Copy(processBuffer, fullGroups, leftoverBuffer, 0, remaining);
                    leftoverCount = remaining;
                }

                // 处理最后的剩余字节（会自动补 '='）
                if (leftoverCount > 0)
                {
                    string final = Convert.ToBase64String(leftoverBuffer, 0, leftoverCount);
                    outputWriter.Write(final);
                }
            }
        }
    }
}
