import getpass
import re
import urllib.request
from urllib.request import urlopen
from time import sleep
import time
import lxml
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup as bs
import json
from datetime import datetime


#driver = webdriver.Chrome(executable_path="c:\selenium browser drivers\chromedriver.exe")
options = Options()
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)


class Instagram:
    def __init__(self):
        self.driver_location = 'c:\selenium browser drivers\chromedriver.exe'
        self.driver = webdriver.Chrome(self.driver_location)

    def Instagram_LogIn(self): #driver #prihlasenie do Instagramu
        self.driver.get('https://www.instagram.com/accounts/login/?source=auth_switcher')
        sleep(3)

        #akceptovanie cookies
        cookies_window = self.driver.find_element_by_class_name('aOOlW.bIiDR')
        cookies_window.click()
        sleep(1)

        #hladanie pola prihlasovacieho mena a hesla, pomocou XPath
        username_field = self.driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[1]/div/label/input')
        username_field.click()  # kliknutie na policko username
        username_field.send_keys("HashtagAnalysis") #self.userName
        sleep(2)#5

        password_field = self.driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[2]/div/label/input')
        password_field.click()  # kliknutie na policko password
        password_field.send_keys("BP2022")#self.passWord
        sleep(1)#5

        #tlacidlo na prihlasenie
        login_button = self.driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[3]/button/div')
        login_button.click()
        sleep(2)#3

        #vyskakovacie okno
        not_now = self.driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div/div/div/button')
        not_now.click()
        sleep(2)#5

        #notifikacie
        not_now_notice = self.driver.find_element_by_class_name('aOOlW.HoLwm')
        not_now_notice.click()
        sleep(2)#5

    def search_tag(self): #vrati prvy riadok vo vyhladavani pri dany tag
        searchbox = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//input[@placeholder='Hľadať']")))
        searchbox.clear()
        searchbox.send_keys("#bratislava")
        sleep(2)
        self.wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="react-root"]/section/nav/div[2]/div/div/div[2]/div[3]/div/div[2]/div/div[2]/a')))
        searchbox.send_keys(Keys.ENTER)
        sleep(2)
        searchbox.send_keys(Keys.ENTER)

    def get_tag_page(self): #vrati vsetky prispevky pre dany hashtag
        query = "happy"
        page = 'https://www.instagram.com/explore/tags/' + query + "/"
        self.driver.get(page)
        sleep(2)

    def get_location_page(self, query):  # vrati vsetky prispevky pre danu lokalitu
        self.url = 'https://www.instagram.com/explore/locations/' + query + "/"  # url adresa na zbieranie prispevkov
        self.driver.get(self.url)
        sleep(2)


    def scroll(self, timeout):
        scroll_pause_time = timeout
        #last_height = self.driver.execute_script("return document.body.scrollHeight")
        while True:
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(scroll_pause_time)
            new_height = self.driver.execute_script("return document.body.scrollHeight")
            if new_height == last_height:
                break
            last_height = new_height

    def all_links(self): #prvych 600 príspevkov
        #driver = webdriver.Chrome(options=options, executable_path='./geckodriver')
        #self.driver.implicitly_wait(30)

        self.driver.get(self.url)
        last_height = self.driver.execute_script("return document.body.scrollHeight")
        self.links = []

        #target = input("Zadaj počet príspevkov pre lokalitu: ")
        soup_a = bs(self.driver.page_source, 'html.parser')
        #soup_a = bs(self.driver.page_source, 'lxml')

        while True:
            soup_a = bs(self.driver.page_source, 'html.parser')
            for link in soup_a.find_all('a'):
                if re.match("/p", link.get('href')):
                    self.links.append('https://www.instagram.com'+link.get('href'))
                else:
                    continue
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(2)
            new_height = self.driver.execute_script("return document.body.scrollHeight")
            if new_height == last_height:
                break
            last_height = new_height
            print("Scraped ", len(self.links), " links, ", len(set(self.links)), ' are unique')
        print("Zoznam príspevkov:", self.links)
        #self.close_webdriver()
        #return list(set(links))  #URL odkazy s danou lokalitou

    def getJson(self):
        page = urlopen(self.url).read()
        data = bs(page, 'html.parser')
        body = data.find('body')
        script = body.find('script')
        raw = script.text.strip().replace('window._sharedData =', '').replace(';', '')
        self.json_data = json.loads(raw)
        print(self.json_data)
        return self.json_data

    def postDate(self):
        return datetime.utcfromtimestamp(
            self.json_data['entry_data']['PostPage'][0]['graphql']['shortcode_media']['taken_at_timestamp']).strftime(
            '%Y-%m-%d %H:%M:%S')

    def close_webdriver(self): #zatvorenie webdriveru
        self.driver.close()

i = Instagram()
i.Instagram_LogIn()
i.get_location_page("105397431195650")
i.all_links()
i.getJson()
#i.postDate()
#i.get_tag_page()
#i.get_location_page("213682323") #id 105397431195650/ id pre lokalitu Bratislava 213682323 #i.scroll(5)
