using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using Serilog;

namespace CONTROLLER.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UploadController : ControllerBase
    {
        // S3配置信息
        private readonly string _bucketName = "pod";
        private readonly string _accessKey = "EDEW1KIIRBIE7DXRPFJ4";
        private readonly string _secretKey = "g5jP7I8Ge3WwmbNbtutO7kPL3WWxOcjcNnmcR29J";
        private readonly string _endpoint = "https://pod.us-ord-1.linodeobjects.com";

        [HttpPost]
        public async Task<IActionResult> Upload([FromForm] List<IFormFile> files, [FromForm] string type, [FromForm] string handoverNumber, [FromForm] List<string> uniqueIds)
        {
            try
            {
                if (files == null || files.Count == 0)
                {
                    return BadRequest(new { code = 1, message = "No files uploaded" });
                }

                var uploadedUrls = new List<string>();

                // 生成年月前缀（与前端保持一致，使用ISO格式）
                string yearMonth = DateTime.Now.ToString("yyyyMM");
                string prefix = string.Empty;

                // 根据类型设置前缀
                if (type == "arrival")
                {
                    prefix = $"arrivalhandover/{yearMonth}/";
                }
                else if (type == "shipping")
                {
                    prefix = $"shippinghandover/{yearMonth}/";
                }
                else
                {
                    prefix = "pod/";
                }

                for (int i = 0; i < files.Count; i++)
                {
                    var file = files[i];
                    if (file.Length > 0)
                    {
                        // 生成唯一的文件名
                        string fileName;
                        if (!string.IsNullOrEmpty(handoverNumber) && uniqueIds != null && i < uniqueIds.Count)
                        {
                            // 使用交接单号和前端传递的唯一ID生成文件名，与前端预生成的链接保持一致
                            var uniqueId = uniqueIds[i];
                            fileName = $"{handoverNumber}_{uniqueId}_{Path.GetFileName(file.FileName)}";
                        }
                        else if (!string.IsNullOrEmpty(handoverNumber))
                        {
                            // 使用交接单号生成文件名
                            var uniqueId = Guid.NewGuid().ToString("N");
                            fileName = $"{handoverNumber}_{uniqueId}_{Path.GetFileName(file.FileName)}";
                        }
                        else
                        {
                            // 传统方式生成文件名
                            fileName = $"{Guid.NewGuid().ToString("N")}_{Path.GetFileName(file.FileName)}";
                        }
                        var objectKey = prefix + fileName;

                        // 上传到S3兼容存储
                        using (var stream = file.OpenReadStream())
                        {
                            byte[] fileData = new byte[file.Length];
                            await stream.ReadAsync(fileData, 0, (int)file.Length);
                            
                            bool success = await UploadToS3(fileData, _bucketName, objectKey, _accessKey, _secretKey, _endpoint, file.ContentType);
                            
                            if (success)
                            {
                                // 生成访问URL
                                var fileUrl = $"{_endpoint}/{objectKey}";
                                uploadedUrls.Add(fileUrl);
                            }
                            else
                            {
                                throw new Exception("Failed to upload file to S3");
                            }
                        }
                    }
                }

                Log.Information("Files uploaded successfully: {Count}", uploadedUrls.Count);
                return Ok(new { code = 0, message = "Upload successful", data = uploadedUrls });
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error uploading files");
                return StatusCode(500, new { code = 2, message = "Upload failed: " + ex.Message });
            }
        }

        [HttpGet]
        public IActionResult UploadGet()
        {
            return BadRequest(new { code = 3, message = "Method not allowed. Please use POST request for file upload." });
        }

        /// <summary>
        /// 使用Access Key和Secret Key直接上传文件到S3兼容存储
        /// </summary>
        /// <param name="fileData">文件数据</param>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="objectKey">对象键</param>
        /// <param name="accessKey">S3访问密钥</param>
        /// <param name="secretKey">S3密钥</param>
        /// <param name="endpoint">S3兼容存储端点</param>
        /// <param name="contentType">文件MIME类型</param>
        /// <returns>是否成功</returns>
        private async Task<bool> UploadToS3(byte[] fileData, string bucketName, string objectKey, string accessKey, string secretKey, string endpoint, string contentType)
        {
            try
            {
                // 准备上传URL
                string url = $"{endpoint}/{objectKey}";
                
                // 生成日期和签名
                string date = DateTime.UtcNow.ToString("r");
                string host = new Uri(endpoint).Host;
                
                // 生成签名所需的字符串
                string canonicalizedAmzHeaders = "x-amz-acl:public-read\n";
                string canonicalizedResource = $"/{bucketName}/{objectKey}";
                string stringToSign = $"PUT\n\n{contentType}\n{date}\n{canonicalizedAmzHeaders}{canonicalizedResource}";
                string signature = CalculateSignature(stringToSign, secretKey);
                
                // 设置全局SSL/TLS配置
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
                
                // 使用HttpClient进行上传
                using (var client = new System.Net.Http.HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(60); // 60秒超时
                    
                    // 创建请求内容
                    var content = new System.Net.Http.ByteArrayContent(fileData);
                    
                    // 设置请求头
                    content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
                    client.DefaultRequestHeaders.Add("Date", date);
                    client.DefaultRequestHeaders.Add("Host", host);
                    client.DefaultRequestHeaders.Add("x-amz-acl", "public-read");
                    client.DefaultRequestHeaders.Add("Authorization", $"AWS {accessKey}:{signature}");
                    
                    // 执行请求
                    var response = await client.PutAsync(url, content);
                    
                    // 验证上传是否成功
                    if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NoContent)
                    {
                        Log.Information("File uploaded to S3 successfully: {ObjectKey}", objectKey);
                        return true;
                    }
                    else
                    {
                        // 输出详细的错误信息
                        string errorContent = await response.Content.ReadAsStringAsync();
                        Log.Error("Upload failed, status code: {StatusCode}, Content: {Content}", response.StatusCode, errorContent);
                        throw new Exception($"Failed to upload file to S3, status code: {response.StatusCode}");
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error uploading file to S3");
                throw;
            }
        }

        /// <summary>
        /// 计算S3请求签名
        /// </summary>
        /// <param name="stringToSign">要签名的字符串</param>
        /// <param name="secretKey">S3密钥</param>
        /// <returns>Base64编码的签名</returns>
        private string CalculateSignature(string stringToSign, string secretKey)
        {
            using (HMACSHA1 hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey)))
            {
                byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
                return Convert.ToBase64String(hashBytes);
            }
        }
    }
}