<!DOCTYPE html>
<html>

  <head>
    <script data-require="angularjs@1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
  </head>

  <body ng-app="app">
    <catalog></catalog>
    <script src="script.js"></script>
  </body>
</html>
function ApiService ($timeout) {
    this.getProducts = () => {
        // simulate async http request
        // and server response latency
        return $timeout(() => {
            return [{
                id: 1,
                title: 'Fourrure d\'épiderme',
                description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit`,
                img: 'http://lorempixel.com/200/200/sports/'
            }, {
                id: 2,
                title: 'Steak pré-maché',
                description: `Sed ut perspiciatis unde omnis iste natus error
                    sit voluptatem accusantium`,
                img: 'http://lorempixel.com/200/200/people/'
            }, {
                id: 3,
                title: 'Crème de jouvence',
                description: 'At vero eos et accusamus et iusto odio dignissimos ducimus',
                img: 'http://lorempixel.com/200/200/nature/'
            }, {
                id: 4,
                title: 'Vase antique',
                description: `On the other hand, we denounce with righteous indignation and`,
                img: 'http://lorempixel.com/200/200/food/'
            }];
        }, 200);
    };

    this.addToCart = product => {
        return $timeout(() => {
            return {
                status: 201,
                statusText: 'Created',
                data: null
            };
        }, 200);
    };
    
    this.removeFromCart = product => {
        return $timeout(() => {
            return {
                status: 204,
                statusText: 'No Content',
                data: null
            };
        }, 200);
    };
}

const CatalogComponent = {
    template: `
        <h1>Amazonie</h1>
        <div>
            <h2>Nos produits exclusivements uniques</h2>
            <section style="display: flex; justify-content: space-between; padding: 0 20px;">
                <product style="padding: 1%;"
                    ng-repeat="product in $catalog.products track by product.id"
                    data="product"
                    add-to-cart="$catalog.addToCart(product)">                    
                </product>
            </section>
            <div ng-if="$catalog.fetching">Chargement ...</div>
            <cart 
                data="$catalog.cart" 
                loading="$catalog.loading" 
                remove-from-cart="$catalog.removeFromCart(product)">
            </cart>
        </div>
    `,
    require: '^product',
    controller: class CatalogCtrl {
        constructor (ApiService, $log) { // ne pas oublier $inject sur un build minifié
            this.ApiService = ApiService;
            this.$log = $log;

            this.products = [];
            this.cart = [];
        }
        
        $onInit () {
            this.fetching = true;
            this.ApiService.getProducts()
                .then((products) => {
                    this.products = this.products.concat(products);
                })
                .finally(() => this.fetching = false)
                .catch((error) => this.$log.error(error));
        }

        addToCart (product) {
            if (angular.isDefined(product.quantity) &&
                angular.isNumber(product.quantity) &&
                product.quantity > 0
            ) {
                this.loading = true;
                this.ApiService.addToCart(product)
                    .then(() => this.cart = this.cart.concat(
                        angular.copy(product)
                    ))
                    .finally(() => {
                        product.quantity = undefined; // reset input quantity
                        this.loading = false;
                    })
                    .catch((error) => this.$log.error(error));
            }
        }
        
        removeFromCart (product) {
            if (this.cart.indexOf(product) > -1) {
                this.loading = true;
                this.ApiService.removeFromCart()
                    .then(() => {
                        let remaining = angular
                            .copy(this.cart)
                            .filter((remainingProduct) => {
                                return product.id !== remainingProduct.id;
                            });
                        this.cart = remaining;
                    })
                    .finally(() => this.loading = false)
                    .catch((error) => this.$log.error(error));
            }
        }
    },
    controllerAs: '$catalog',
    transclude: false
};

const ProductComponent = {
    bindings: {
        data: '<',
        addToCart: '&'
    },
    require: '^catalog',
    template: `
        <article style="height: 100%; display:flex; flex-direction: column; justify-content: space-around;">
            <header style="display: block">
                <img ng-src="{{ $product.data.img }}" 
                    alt="{{ $prodct.data.id + '-product-image' }}"
                    style="display: block; max-width: 100%">
                <h3>{{ $product.data.title }}</h3>
                <p>{{ $product.data.description }}</p>
            </header>
            <section style="padding: 10px 0;">
                <label for="{{ $product.data.id }}">Qté</label>
                <input id="{{ $product.data.id }}"
                    type="number"
                    ng-model="$product.data.quantity"/>
            </section>
            <footer>
                <button type="button" 
                    ng-click="$product.addToCart({ product: $product.data})"
                    ng-disabled="!$product.data.quantity || $product.data.quantity == 0">
                    Ajouter au panier
                </button>
            </footer>
        </article>
    `,
    transclude: false,
    controllerAs: '$product'
};

const CartComponent = {
    bindings: {
        data: '<',
        loading: '<',
        removeFromCart: '&'
    },
    require: '^catalog',
    template: `
        <section>
            <h4>Mon panier</h4>
            <div style="color: #87a800" ng-repeat="product in $cart.data">
                <strong>{{ product.title }}</strong> x {{ product.quantity }} 
                <button type="button" 
                    ng-click="$cart.removeFromCart({ product })">
                    Supprimer
                </button>
            </div>
            <div ng-if="$cart.data.length == 0 && !$cart.loading">Vide</div>
            <div ng-if="$cart.loading">Chargement en cours...</div>
        </section>
    `,
    transclude: false,
    controllerAs: '$cart'
};


angular
    .module('app', [])
    .service('ApiService', ApiService)
    .component('cart', CartComponent)
    .component('product', ProductComponent)
    .component('catalog', CatalogComponent);