using System.Globalization;
using System.Security.Cryptography;
using System.Text;

namespace CouponReport.Service
{
	public class ReportService
	{
		public string GetTenantCode(string externalSystemKey) 
		{
			var result = DESDecode(externalSystemKey);
			var tenantNo = result.Split("|")[7];
			return tenantNo.Substring(0, 8);
		}

		public string GetInvoiceNo(string externalSystemKey) 
		{
			var result = DESDecode(externalSystemKey);
			return result.Split("|")[3];
		}

		public decimal GetInvoiceMoney(string externalSystemKey)
		{
			var result = DESDecode(externalSystemKey);
			return decimal.Parse(result.Split("|")[4]);
		}

		public DateTime GetInvoiceDateTime(string externalSystemKey)
		{
			var result = DESDecode(externalSystemKey);
			return DateTime.ParseExact(result.Split("|")[5], "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
		}

		private string DESDecode(string externalSystemKey)
		{
			if (string.IsNullOrWhiteSpace(externalSystemKey))
			{
				return string.Empty;
			}

			var key = "RAdWIMPs";

			var cipherHex = externalSystemKey.StartsWith("YLC", StringComparison.OrdinalIgnoreCase)
				? externalSystemKey.Substring(3)
				: externalSystemKey;

			if (cipherHex.Length % 2 != 0)
			{
				throw new ArgumentException("Invalid coupon cipher text.", nameof(externalSystemKey));
			}

			var cipherBytes = new byte[cipherHex.Length / 2];
			for (var i = 0; i < cipherBytes.Length; i++)
			{
				cipherBytes[i] = Convert.ToByte(cipherHex.Substring(i * 2, 2), 16);
			}

			using var desProvider = new DESCryptoServiceProvider
			{
				Key = Encoding.ASCII.GetBytes(key),
				IV = Encoding.ASCII.GetBytes(key),
				Mode = CipherMode.CBC,
				Padding = PaddingMode.PKCS7
			};

			using var memoryStream = new MemoryStream();
			using (var cryptoStream = new CryptoStream(memoryStream, desProvider.CreateDecryptor(), CryptoStreamMode.Write))
			{
				cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
				cryptoStream.FlushFinalBlock();
			}

			return Encoding.UTF8.GetString(memoryStream.ToArray());
		}
	}
}
