using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Configuration;
using Newtonsoft.Json;

namespace Common
{
	public sealed class WeiXinHelper
	{
		public static string AppId 
		{
			get { return ConfigurationManager.AppSettings["WeiXinAppId"]; }
		}

		public static string AppSecret
		{
			get { return ConfigurationManager.AppSettings["WeiXinAppSecret"]; }
		}

		public static WeiXinAccessToken GetAccessToken()
		{
			string accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret;

            using (WebClient client = new WebClient())
            {
                string result = client.DownloadString(accessTokenUrl);
                return JsonConvert.DeserializeObject<WeiXinAccessToken>(result);
            }
		}

		public static WeiXinJsApiTicket GetJsApiTicket(string accessToken)
		{
			string jsApiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";

            using (WebClient client = new WebClient())
            {
                string result = client.DownloadString(jsApiTicketUrl);
                return JsonConvert.DeserializeObject<WeiXinJsApiTicket>(result);
            }
		}

		public static string CreateJsApiSignature(string jsApiTicket, string noncestr, int timestamp, string url)
		{
			string str = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;

			byte[] data = Encoding.Default.GetBytes(str);

			byte[] hashcode = System.Security.Cryptography.SHA1.Create().ComputeHash(data);

			return BitConverter.ToString(hashcode).Replace("-", "").ToLower();
		}

		public static string CreateNonceStr(uint length = 16)
		{
			string noncestr = "";

			string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

			Random rand = new Random((int)DateTime.Now.Ticks);

			for (int i = 0; i < length; i++)
			{
				noncestr += chars[rand.Next(chars.Length - 1)];
			}

			return noncestr;
		}

		public static int GetCurrentTimeStamp()
		{
			System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
			return (int)(DateTime.Now - startTime).TotalSeconds;
		}
	}

	public class WeiXinResult
	{
		[JsonProperty("errcode")]
		public int ErrorCode { get; set; }

		[JsonProperty("errmsg")]
		public string ErrorMsg { get; set; }
	}

	public class WeiXinAccessToken : WeiXinResult
	{
		[JsonProperty("access_token")]
		public string AccessToken { get; set; }

		[JsonProperty("expires_in")]
		public int ExpiresIn { get; set; }
	}

	public class WeiXinJsApiTicket : WeiXinResult
	{
		[JsonProperty("ticket")]
		public string Ticket { get; set; }

		[JsonProperty("expires_in")]
		public int ExpiresIn { get; set; }
	}
}
