from datetime import datetime

import requests
from sqlalchemy.orm import sessionmaker

from service.helper import get_tray_url, parse_date, get_paged_data
from db.helpers import get_engine
from db.models import Product, Category, ProductsSold


class ProductService():
    access_token = None
    session = None
    limiter = None

    def __init__(self, access_token, limiter):
        self.access_token = access_token
        Session = sessionmaker(bind=get_engine())
        self.session = Session()
        self.limiter = limiter

    def save_all_products(self):
        params = {
            'access_token': self.access_token
        }
        json_products = get_paged_data('products', 'Products',  self.limiter, max_pages=None, params=params)
        self.save_products(json_products)

    def save_all_products_sold(self):
        params = {
            'access_token': self.access_token
        }
        json_products_sold = get_paged_data('products_solds', 'ProductsSolds', self.limiter, max_pages=None, params=params)
        self.save_products_sold(json_products_sold)

    def save_all_categories(self):
        params = {
            'access_token': self.access_token
        }
        json_categories = get_paged_data('categories', 'Categories', self.limiter, max_pages=None, params=params)
        self.save_categories(json_categories)

    def parse_product(self, json_product):
        return Product(
            id=int(json_product['id']),
            modified=datetime.strptime(json_product['modified'], '%Y-%m-%d %H:%M:%S'),
            ean=json_product['ean'],
            is_kit=bool(json_product['is_kit']),
            slug=json_product['slug'],
            ncm=json_product['ncm'],
            activation_date=parse_date(json_product['activation_date']),
            deactivation_date=parse_date(json_product['deactivation_date']),
            name=json_product['name'],
            price=float(json_product['price']),
            cost_price=float(json_product['cost_price']),
            dollar_cost_price=float(json_product['dollar_cost_price']),
            promotional_price=float(json_product['promotional_price']),
            start_promotion=parse_date(json_product['start_promotion']),
            end_promotion=parse_date(json_product['end_promotion']),
            brand=json_product['brand'],
            brand_id=json_product['brand_id'],
            model=json_product['model'],
            weight=float(json_product['weight']),
            length=float(json_product['length']),
            width=float(json_product['width']),
            height=float(json_product['height']),
            stock=int(json_product['stock']),
            category_id=int(json_product['category_id']),
            available=bool(json_product['available']),
            availability=str(json_product['availability']),
            reference=str(json_product['reference']),
            hot=bool(json_product['hot']),
            release=bool(json_product['release']),
            additional_button=bool(json_product['additional_button']),
            has_variation=bool(json_product['has_variation']),
            rating=float(json_product['rating']),
            count_rating=int(json_product['count_rating']),
            quantity_sold=int(json_product['quantity_sold']),
            url=json_product['url'],
            created=datetime.strptime(json_product['created'], '%Y-%m-%d %H:%M:%S'),
            payment_option=str(json_product['payment_option']),
            payment_option_details=json_product['payment_option_details'],
            related_categories=json_product['related_categories'],
            release_date=parse_date(json_product['release_date']),
            shortcut=json_product['shortcut'],
            virtual_product=bool(json_product['virtual_product']),
            minimum_stock=int(json_product['minimum_stock']),
            minimum_stock_alert=bool(int(json_product['minimum_stock_alert'])),
            free_shipping=bool(json_product['free_shipping']),
            video=json_product['video'],
            metatag=json_product['metatag'],
            payment_option_html=json_product['payment_option_html'],
            upon_request=bool(json_product['upon_request']),
            available_for_purchase=bool(json_product['available_for_purchase']),
            # all_categories=json_product['all_categories'], #Todo
            all_categories=None,
            product_image=json_product['product_image'] if 'product_image' in json_product else None,
            variant=json_product['variant'] if 'variant' in json_product else None,
            additional_infos=json_product['additional_infos'] if 'additional_infos' in json_product else None,
        )

    def parse_category(self, json_category):
        return Category(
            id=int(json_category['id']),
            parent_id=int(json_category['parent_id']) if json_category['parent_id'] in json_category else None,
            name=json_category['name'],
            small_description=json_category['small_description'],
            images=json_category['Images']
        )

    def parse_products_sold(self, json_products_sold):
        return ProductsSold(
            id=int(json_products_sold['id']),
            product_id=int(json_products_sold['product_id']),
            order_id=int(json_products_sold['order_id']),
            name=json_products_sold['name'],
            price=float(json_products_sold['price']),
            original_price=float(json_products_sold['original_price']),
            quantity=int(json_products_sold['quantity']),
            model=json_products_sold['model'],
            reference=json_products_sold['reference'],
            variant_id=int(json_products_sold['variant_id']),
            additional_information=json_products_sold['additional_information'],
        )

    def save_products_sold(self, json_products_sold):
        for json_ps in json_products_sold:
            products_sold = self.parse_products_sold(json_ps['ProductsSold'])
            self.session.merge(products_sold)
        self.session.commit()

    def save_categories(self, json_categories):
        for json_category in json_categories:
            category = self.parse_category(json_category['Category'])
            self.session.merge(category)

        self.session.commit()

    def save_products(self, json_products):
        for json_product in json_products:
            product = self.parse_product(json_product['Product'])
            self.session.merge(product)

        self.session.commit()
