(function (angular, $, _, d3) {


  // FIXME: This code is long and hasn't been fully working for me, but I've moved it into a spot
  // where it at least fits in a bit better.

  // example: <div crm-mailing-ab-stats="{split_count: 6, criteria:'Open'}" crm-abtest="myabtest" />
  // options (see also: Mailing.graph_stats API)
  //  - split_count: int
  //  - criteria: string
  //  - target_date: string, date
  //  - target_url: string
  angular.module('crmMailingAB').directive('crmMailingAbStats', function (crmApi, $parse) {
    return {
      scope: {
        crmMailingAbStats: '@',
        crmAbtest: '@'
      },
      template: '<div class="crm-mailing-ab-stats"></div>',
      link: function (scope, element, attrs) {
        var abtestModel = $parse(attrs.crmAbtest);
        var optionModel = $parse(attrs.crmMailingAbStats);
        var options = angular.extend({}, optionModel(scope.$parent), {
          criteria: 'Open', // e.g. 'Open', 'Total Unique Clicks'
          split_count: 5
        });

        scope.$watch(attrs.crmAbtest, refresh);
        function refresh() {
          var abtest = abtestModel(scope.$parent);
          if (!abtest) {
            console.log('failed to draw stats - missing abtest');
            return;
          }

          scope.graph_data = [
            {},
            {},
            {},
            {},
            {}
          ];
          var keep_cnt = 0;

          for (var i = 1; i <= options.split_count; i++) {
            var result = crmApi('MailingAB', 'graph_stats', {
              id: abtest.ab.id,
              target_date: abtest.ab.declare_winning_time ? abtest.ab.declare_winning_time : 'now',
              target_url: null, // FIXME
              criteria: options.criteria,
              split_count: options.split_count,
              split_count_select: i
            });
            /*jshint -W083 */
            result.then(function (data) {
              var temp = 0;
              keep_cnt++;
              for (var key in data.values.A) {
                temp = key;
              }
              var t = data.values.A[temp].time.split(" ");
              var m = t[0];
              var year = t[2];
              var day = t[1].substr(0, t[1].length - 3);
              var t1, hur, hour, min;
              if (_.isEmpty(t[3])) {
                t1 = t[4].split(":");
                hur = t1[0];
                if (t[5] == "AM") {
                  hour = hur;
                  if (hour == 12) {
                    hour = 0;
                  }
                }
                if (t[5] == "PM") {
                  hour = parseInt(hur) + 12;
                }
                min = t1[1];
              }
              else {
                t1 = t[3].split(":");
                hur = t1[0];
                if (t[4] == "AM") {
                  hour = hur;
                  if (hour == 12) {
                    hour = 0;
                  }
                }
                if (t[4] == "PM") {
                  hour = parseInt(hur) + 12;
                }
                min = t1[1];
              }
              var month = 0;
              switch (m) {
                case "January":
                  month = 0;
                  break;
                case "February":
                  month = 1;
                  break;
                case "March":
                  month = 2;
                  break;
                case "April":
                  month = 3;
                  break;
                case "May":
                  month = 4;
                  break;
                case "June":
                  month = 5;
                  break;
                case "July":
                  month = 6;
                  break;
                case "August":
                  month = 7;
                  break;
                case "September":
                  month = 8;
                  break;
                case "October":
                  month = 9;
                  break;
                case "November":
                  month = 10;
                  break;
                case "December":
                  month = 11;
                  break;

              }
              var tp = new Date(year, month, day, hour, min, 0, 0);
              scope.graph_data[temp - 1] = {
                time: tp,
                x: data.values.A[temp].count,
                y: data.values.B[temp].count
              };

              if (keep_cnt == options.split_count) {
                scope.graphload = true;
                data = scope.graph_data;

                // set up a colour variable
                var color = d3.scale.category10();

                // map one colour each to x, y and z
                // keys grabs the key value or heading of each key value pair in the json
                // but not time
                color.domain(d3.keys(data[0]).filter(function (key) {
                  return key !== "time";
                }));

                // create a nested series for passing to the line generator
                // it's best understood by console logging the data
                var series = color.domain().map(function (name) {
                  return {
                    name: name,
                    values: data.map(function (d) {
                      return {
                        time: d.time,
                        score: +d[name]
                      };
                    })
                  };
                });

                // Set the dimensions of the canvas / graph
                var margin = {
                    top: 30,
                    right: 20,
                    bottom: 40,
                    left: 75
                  },
                  width = 550 - margin.left - margin.right,
                  height = 350 - margin.top - margin.bottom;

                // Set the ranges
                //var x = d3.time.scale().range([0, width]).domain([0,10]);
                var x = d3.time.scale().range([0, width]);
                var y = d3.scale.linear().range([height, 0]);

                // Define the axes
                var xAxis = d3.svg.axis().scale(x)
                  .orient("bottom").ticks(10);

                var yAxis = d3.svg.axis().scale(y)
                  .orient("left").ticks(5);

                // Define the line
                // Note you plot the time / score pair from each key you created earlier
                var valueline = d3.svg.line()
                  .x(function (d) {
                    return x(d.time);
                  })
                  .y(function (d) {
                    return y(d.score);
                  });

                // Adds the svg canvas
                var svg = d3.select($('.crm-mailing-ab-stats', element)[0])
                  .append("svg")
                  .attr("width", width + margin.left + margin.right)
                  .attr("height", height + margin.top + margin.bottom)
                  .append("g")
                  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                // Scale the range of the data
                x.domain(d3.extent(data, function (d) {
                  return d.time;
                }));

                // note the nested nature of this you need to dig an additional level
                y.domain([
                  d3.min(series, function (c) {
                    return d3.min(c.values, function (v) {
                      return v.score;
                    });
                  }),
                  d3.max(series, function (c) {
                    return d3.max(c.values, function (v) {
                      return v.score;
                    });
                  })
                ]);
                svg.append("text")      // text label for the x axis
                  .attr("x", width / 2)
                  .attr("y", height + margin.bottom)
                  .style("text-anchor", "middle")
                  .text("Time");

                svg.append("text")      // text label for the x axis
                  .style("text-anchor", "middle")
                  .text(scope.winnercriteria).attr("transform",function (d) {
                    return "rotate(-90)";
                  }).attr("x", -height / 2)
                  .attr("y", -30);

                // create a variable called series and bind the date
                // for each series append a g element and class it as series for css styling
                series = svg.selectAll(".series")
                  .data(series)
                  .enter().append("g")
                  .attr("class", "series");

                // create the path for each series in the variable series i.e. x, y and z
                // pass each object called x, y nad z to the lne generator
                series.append("path")
                  .attr("class", "line")
                  .attr("d", function (d) {
                    // console.log(d); // to see how d3 iterates through series
                    return valueline(d.values);
                  })
                  .style("stroke", function (d) {
                    return color(d.name);
                  });

                // Add the X Axis
                svg.append("g") // Add the X Axis
                  .attr("class", "x axis")
                  .attr("transform", "translate(0," + height + ")")
                  .call(xAxis)
                  .selectAll("text")
                  .attr("transform", function (d) {
                    return "rotate(-30)";
                  });

                // Add the Y Axis
                svg.append("g") // Add the Y Axis
                  .attr("class", "y axis")
                  .call(yAxis);
              }
            });
          }
        }
      } // link()
    };
  });
})(angular, CRM.$, CRM._, CRM.visual.d3);
