﻿/*
* Copyright (c) 2013-2014 Filipe Badaro
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using HtmlAgilityPack;
using MtgPriceOptimizer.Model;

namespace MtgPriceOptimizer.Stores
{
    public class CoolStuffInc : BaseStore
    {
        private const string _searchUrl = "http://www.coolstuffinc.com/main_search.php?pa=searchOnName&page=<page>&sid=1&resultsPerPage=25&q=<term>";

        public override string Name
        {
            get { return "CoolStuffInc"; }
        }

        protected override IEnumerable<Product> GetStoreProducts(string cardName, string comparisonCardName, string searchExpression)
        {
            string searchUrl = _searchUrl.Replace("<term>", Uri.EscapeDataString(searchExpression));

            List<Product> products = new List<Product>();

            int page = 1;
            bool hasMorePages;
            do
            {
                hasMorePages = false;

                string content = Encoding.UTF8.GetString(new WebClient().DownloadData(searchUrl.Replace("<page>", page.ToString())));
                page++;

                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(content);

                HtmlNodeCollection productRows = doc.DocumentNode.SelectNodes("//tr[@itemtype='http://schema.org/Product']");

                if (productRows != null)
                {
                    hasMorePages = true;

                    foreach (HtmlNode productRow in productRows)
                    {
                        HtmlNode nameSpan = productRow.SelectSingleNode("td[@class='vm description']/h3/a/span[@itemprop='name']");
                        HtmlNode urlLink = productRow.SelectSingleNode("td[@class='vm description']/h3/a");
                        HtmlNodeCollection priceRows = productRow.SelectNodes("td[@class='vm products']/table/tbody/tr");

                        string name = NormalizeCardName(nameSpan.InnerText);
                        string url = "http://www.coolstuffinc.com" + urlLink.Attributes["href"].Value;
                        string currency = "USD";

                        // CSI may have multiple qualities (NM, Played, Foil) of the same card
                        List<double> prices = new List<double>();
                        List<bool> availabilities = new List<bool>();

                        foreach (HtmlNode priceRow in priceRows)
                        {
                            HtmlNode priceSpan = priceRow.SelectNodes("td[@class='c vm pPrice']/span").Last();
                            if (priceSpan != null)
                            {
                                prices.Add(double.Parse(priceSpan.InnerText.Replace("$", "").Trim(), new CultureInfo("en-US")));
                                availabilities.Add(priceSpan.Attributes["class"].Value != "strike");
                            }
                            else
                            {
                                prices.Add(0);
                                availabilities.Add(false);
                            }
                        }

                        int bestIndex = availabilities.IndexOf(true);
                        if (bestIndex < 0) bestIndex = 0;

                        if (name.ToUpperInvariant() == NormalizeCardName(comparisonCardName).ToUpperInvariant())
                        {
                            products.Add(new Product()
                            {
                                Name = cardName,
                                Price = prices[bestIndex],
                                Currency = currency,
                                Available = availabilities[bestIndex],
                                Url = url
                            });
                        }
                    }
                }

                HtmlNode currentSpan = doc.DocumentNode.SelectSingleNode("//span[@id='nextLink']");
                hasMorePages = currentSpan != null;

            } while (hasMorePages);

            return (products);
        }
    }
}
