import json
import datetime

from bs4 import BeautifulSoup
from utils.tasks import insert_product_info_task, insert_product_reviews_task, insert_product_stat_task

review_headers = {
    'accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'en-US,en;q=0.9',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}

headers = {
    'accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'en-US,en;q=0.9',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
}


class Walmart:
    product_info = None
    product_reviews = None

    def __init__(self, sku, session):
        self.sku = sku
        self.session = session

    @staticmethod
    def parse_data(data):
        parsed_data = data['props']['pageProps']['initialData']
        parsed_data['data']['contentLayout'].pop('pageMetadata', None)
        parsed_data['data'].pop('seoItemMetaData', None)
        parsed_data['local'] = data['locale']
        parsed_data['locals'] = data['locales']
        parsed_data['defaultLocale'] = data['defaultLocale']
        return parsed_data

    def get_product_reviews(self, sku, page):
        def _make_request():
            url = f'https://www.walmart.com/reviews/product/{sku}?sort=relevancy&page={page}'
            response = self.session.get(url, headers=review_headers)
            soup = BeautifulSoup(response.text, 'html.parser')
            data = soup.select_one('#__NEXT_DATA__')
            data = json.loads(data.text)
            next_batch = data['props']['pageProps']['initialData']['data']['reviews']['pagination']['next']
            customer_reviews = data['props']['pageProps']['initialData']['data']['reviews']['customerReviews']
            review_stats = data['props']['pageProps']['initialData']['data']['reviews']
            review_stats.pop('customerReviews', None)
            review_stats.pop('pagination', None)
            return customer_reviews, next_batch, review_stats

        reviews, next_url, stats = _make_request()
        reviews = [{
            'review_id': review['reviewId'],
            'sku': sku,
            'created': datetime.datetime.now(),
            'last_updated': datetime.datetime.now(),
            'review': review
        } for review in reviews]
        self.product_reviews = reviews
        # This loop is for scraping all reviews
        # while next_url:
        #     reviews, next_url, stats = _make_request()
        #     final_reviews = final_reviews + reviews
        #     page += 1

        # Save Reviews in db
        insert_product_reviews_task.delay(reviews, sku)
        # Save Review Stats to DB
        insert_product_stat_task.delay(stats, sku)
        return reviews, stats

    def get_product_info(self):
        url = f'https://www.walmart.com/ip/seort/{self.sku}'
        response = self.session.get(url, headers=headers)
        if response.status_code == 404:
            return {self.sku: {'status': 404, 'message': 'not found'}}
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')
            data = soup.select_one('#__NEXT_DATA__')
            data = json.loads(data.text)
            self.product_info = self.parse_data(data)
            insert_product_info_task.delay(self.product_info, self.sku)
            return {'status': 200, 'message': 'success', 'result': self.product_info}
