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

public class Script
{
	private string GetDbString(object data)
	{
		return data == DBNull.Value ? "" : (string)data;
	}
	public int GetDbInt(object data)
	{
		if (data == DBNull.Value)
			return -1;

		if (data is byte)
			return (byte)data;
		if (data is int)
			return (int)data;
		if (data is Int64)
			return (int)data;
		if (data is Int32)
			return (int)data;
		if (data is Int16)
			return (int)data;
		if (data is Decimal)
			return (int)data;
		return -1;
	}
	
	
	private ArtistHelper GetArtistInfo(int artistId, INeonScriptHost host)
	{
		var sql = string.Format("SELECT tblArtists.BornName, tblArtists.Biography, tblArtists.Formed, tblArtists.Disbanded, tblArtists.IsArtist FROM tblArtists WHERE tblArtists.Artist_id = {0}", artistId);
		var dataReader = host.RemoteCalls.GetDataReader(sql);
		var row = dataReader.Rows[0];
		return new ArtistHelper 
		{
			BornName = GetDbString(row.Fields[0]),
			Biography =  TrimString(GetDbString(row.Fields[1])),
			Formed = GetDbInt(row.Fields[2]),
			Disbanded = GetDbInt(row.Fields[3]),
			IsArtist = GetDbInt(row.Fields[4]) == 1
		};
	}
	
	private List<AlbumHelper> GetAlbumsFromArtist(string artist, INeonScriptHost host)
	{
		var sb = new StringBuilder();
		sb.AppendLine("select distinct tblAlbums.AlbumName, tblAlbums.AlbumLabel, tblAlbumRating.Rating, tblalbums.releaseyear");
		sb.AppendLine("from tblAlbumRating");
		sb.AppendLine("inner join tblalbums on");
		sb.AppendLine("tblalbums.album_id = tblalbumrating.album_id");
		sb.AppendFormat("where tblalbums.albumartist={0} and tblalbumrating.user_id = {1} ", host.Database.QuotedString(artist), host.Database.ActiveUserId);
		sb.AppendLine("order by tblalbums.releaseyear");
		var sql = sb.ToString();
		var dataReader = host.RemoteCalls.GetDataReader(sql);
		
		var res = new List<AlbumHelper>();
		foreach(var row in dataReader.Rows)
		{
			var item = new AlbumHelper
			{
				Name = GetDbString(row.Fields[0]),
				Label = GetDbString(row.Fields[1]),
				Rating = GetDbInt(row.Fields[2]),
				Year = GetDbInt(row.Fields[3])
			};
			res.Add(item);
		}
		return res;
	}
	
	private string TrimString(string data, int maxLength = 512)
	{
		if (data.Length < maxLength)
			return data;
		return data.Substring(0, maxLength) + "(...)";
	}
			
	private static string htmlEncode(string inData, INeonScriptHost host)
	{
		return host.RemoteCalls.HtmlEncode(inData);
	}

	public bool Run(INeonScriptHost host)
	{
		var outputFolder = host.RemoteCalls.SelectFolder();
		if (outputFolder == "")
			return false;
		var outputFilename = Path.Combine(outputFolder, "artistlist.html");
		var imageFolder = Path.Combine(outputFolder, "_images");
		if (!Directory.Exists(imageFolder))			
			 Directory.CreateDirectory(imageFolder);
			 
		var sb = new StringBuilder();
		
		var artists = host.Artists;
		
		sb.AppendLine("<html>");
		sb.AppendLine("<head>");
		sb.AppendLine("<link rel=\"stylesheet\" href=\"styles.css\" type=\"text/css\">");
		sb.AppendLine("</head>");
		
		sb.AppendLine("<body>");
		
		sb.AppendLine("<table class=\"artists-table\">");

		var idx = 1;		
		foreach(var artist in artists)
		{
			host.UpdateProgress(string.Format("Artist {0}", idx));
			
			sb.AppendLine("<tr>");
			sb.AppendLine("<td>");
			var picture = artist.ArtistPicturePath;
			if (string.IsNullOrEmpty(picture) || !File.Exists(picture))
			{
				picture = artist.ArtistImage; // use cached miniature image
			}
			var currentExt = Path.GetExtension(picture);
			var imageName = Path.Combine(imageFolder, string.Format("art_{0}{1}", artist.ArtistId, currentExt));
			if (File.Exists(picture)) 
			{
				if (File.Exists(imageName))
					File.Delete(imageName);
				File.Copy(picture, imageName);
			}
			
			sb.AppendFormat("<img src=\"{0}\" width=\"160\"/>", imageName);
			sb.AppendLine("</td>");
			sb.AppendLine("<td>");
			sb.AppendFormat("<h2>{0}</h2>", htmlEncode(artist.ArtistName, host));
			
			var artistInfo = GetArtistInfo(artist.ArtistId, host);
			if (!string.IsNullOrEmpty(artistInfo.BornName))
				sb.AppendFormat("<p>Born name:{0}</p>", artistInfo.BornName);
			if (artistInfo.Formed > 0 || artistInfo.Disbanded > 0)
			{
				if (artistInfo.IsArtist)
				{
					sb.AppendFormat("<p>Born:{0}, Died:{1}</p>", artistInfo.Formed, artistInfo.Disbanded);
				}
				else 
				{
					sb.AppendFormat("<p>Formed:{0}, Disbanded:{1}</p>", artistInfo.Formed, artistInfo.Disbanded);
				}
			}
			sb.AppendFormat("<p>{0}</p>", artistInfo.Biography);
			
			sb.AppendLine("</td>");
			sb.AppendLine("</tr>");
			
			// Releases from artist
			var albums = GetAlbumsFromArtist(artist.ArtistName, host);
			sb.AppendLine("<tr>");
			sb.AppendLine("<td colspan=\"2\">");
			
			sb.AppendLine("<table class=\"albums-table\">");
			sb.AppendLine("<tr>");
			sb.AppendLine("<th>Name</th>");
			sb.AppendLine("<th>Year</th>");
			sb.AppendLine("<th>Rating</th>");
			sb.AppendLine("<th>Label</th>");
			sb.AppendLine("</tr>");
			
			foreach(var album in albums)
			{
				sb.AppendLine("<tr>");
				sb.AppendFormat("<td>{0}</td>", album.Name);
				sb.AppendFormat("<td>{0}</td>", album.Year);
				sb.AppendFormat("<td>{0}</td>", host.RemoteCalls.RatingToString(album.Rating));
				sb.AppendFormat("<td>{0}</td>", album.Label);
				sb.AppendLine("</tr>");
			}
			
			sb.AppendLine("</table>");
			
			
			
			sb.AppendLine("</td>");
			sb.AppendLine("</tr>");
			
			
			
			idx++;
		}
		sb.AppendLine("</table>");
		sb.AppendLine("</body>");
		sb.AppendLine("</html>");
		
		File.WriteAllText(outputFilename, sb.ToString());
		
		return true;
	}
}

private class ArtistHelper
{
	public string BornName { get; set; }
	public string Biography { get; set; }
	public int Formed { get; set; }
	public int Disbanded { get; set; }
	public bool IsArtist { get; set; }
}

private class AlbumHelper
{
	public string Name { get; set; }
	public string Label { get; set; }
	public int Rating { get; set; }
	public int Year { get; set; }
}