import { tagged } from "daggy";

const First = tagged("First", ["val"]);

First.prototype.concat = function(that) {
  return this;
};

const Min = tagged("Min", ["val"]);

Min.prototype.concat = function(that) {
  return Min(Math.min(this.val, that.val));
};

const Any = tagged("Any", ["val"]);

Any.prototype.concat = function(that) {
  return Any(this.val || that.val);
};

const Tuple4 = tagged("Tuple4", ["a", "b", "c", "d"]);

Tuple4.prototype.concat = function(that) {
  return Tuple4(
    this.a.concat(that.a),
    this.b.concat(that.b),
    this.c.concat(that.c),
    this.d.concat(that.d)
  );
};

const Customer = tagged("Customer", [
  "name",
  "favouriteThings",
  "registrationDate",
  "hasMadePurchase"
]);

const myStrategy = {
  to: customer =>
    Tuple4(
      First(customer.name),
      customer.favouriteThings,
      Min(customer.registrationDate),
      Any(customer.hasMadePurchase)
    ),

  from: ({ a, b, c, d }) => Customer(a.val, b, c.val, d.val)
};

const merge = strategy => x => y =>
  strategy.from(strategy.to(x).concat(strategy.to(y)));

const Tom1 = Customer("Tom", ["socks"], 100000, false);
const Tom2 = Customer("TomH", ["gloves"], 90000, true);

// { name: 'Tom'
// , favouriteThings: ['socks', 'gloves']
// , registrationDate: 90000
// , hasMadePurchase: true
// }
merge(myStrategy)(Tom1)(Tom2);