import time
from pathlib import Path
import re
from typing import List
from pprint import pprint
from datetime import datetime

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from bs4 import BeautifulSoup as bs

# from .core import SocialMediaParserBase
from social_media.core import SocialMediaParserBase


class InstagramParser(SocialMediaParserBase):
    URL = "https://www.instagram.com"
    COOKIES_DIR = Path("") / "cookies" / "instagram"

    def _login(self, login: str, password: str):
        self.logger.info("Try login as %s", login)
        self.driver.get(self.URL)
        login_field = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='username']"))
        )
        password_field = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='password']"))
        )
        login_button = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, "//button[@type='submit']"))
        )
        login_field.send_keys(login)
        password_field.send_keys(password)
        login_button.click()

        # wait until login loading
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, '//img[@data-testid="user-avatar"]'))
        )

    def search(self, query: str) -> List[dict]:
        self.logger.info("Search for '%s'", query)
        self.driver.get(self.URL)
        search_bar = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='text']"))
        )
        search_bar.send_keys(query)

        # wait until loading result
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="fuqBx "]/div[@role="none"]'))
        )

        # get res
        res_div = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "div[class='fuqBx ']"))
        )

        res = []
        for user_html in bs(res_div.get_attribute('innerHTML'), "html.parser").children:
            link = user_html.findChild("a")['href']
            if not re.search(r'^/[\w.]*/$', link):
                continue
            user_name = user_html.find_all(text=lambda text: bool(text))  # pylint: disable=unnecessary-lambda
            user = {
                "type": "instagram",
                "url": self.URL + link,
                "avatar": user_html.findChild("img")['src'],
                "nickname": user_name[0],
                "name": user_name[1] if len(user_name) > 1 else None,
                "attributes": []
            }
            res.append(user)

        return res

    def get_followers(self, nickname: str) -> List[dict]:
        self.logger.info("Get followers for '%s'", nickname)
        self.driver.get(f"{self.URL}/{nickname}/")

        followers_link = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, f"a[href='/{nickname}/followers/']"))
        )
        followers_link.click()

        while True:
            try:
                end_div = WebDriverWait(self.driver, 5).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "div[class='oMwYe']"))
                )
            except TimeoutException:
                break
            self.driver.execute_script("return arguments[0].scrollIntoView(true);", end_div)
            time.sleep(0.5)

        followers_list = []
        followers_block = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "ul[class='jSC57  _6xe7A']"))
        )
        for user_li_element in bs(followers_block.get_attribute('innerHTML'), "html.parser").find_all("li"):
            user_name = user_li_element.find_all(text=lambda text: bool(text))  # pylint: disable=unnecessary-lambda
            img = user_li_element.findChild("img")
            followers_list.append({
                "avatar": img['src'] if img is not None else None,
                "nickname": user_name[0],
                "name": user_name[2] if len(user_name) >= 4 else None,
            })
        return followers_list

import time
from pathlib import Path
import re
from typing import List
from pprint import pprint
from datetime import datetime

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from bs4 import BeautifulSoup as bs

# from .core import SocialMediaParserBase
from social_media.core import SocialMediaParserBase


class InstagramParser(SocialMediaParserBase):
    URL = "https://www.instagram.com"
    COOKIES_DIR = Path("") / "cookies" / "instagram"

    def _login(self, login: str, password: str):
        self.logger.info("Try login as %s", login)
        self.driver.get(self.URL)
        login_field = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='username']"))
        )
        password_field = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='password']"))
        )
        login_button = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, "//button[@type='submit']"))
        )
        login_field.send_keys(login)
        password_field.send_keys(password)
        login_button.click()

        # wait until login loading
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, '//img[@data-testid="user-avatar"]'))
        )

    def search(self, query: str) -> List[dict]:
        self.logger.info("Search for '%s'", query)
        self.driver.get(self.URL)
        search_bar = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='text']"))
        )
        search_bar.send_keys(query)

        # wait until loading result
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.XPATH, '//div[@class="fuqBx "]/div[@role="none"]'))
        )

        # get res
        res_div = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "div[class='fuqBx ']"))
        )

        res = []
        for user_html in bs(res_div.get_attribute('innerHTML'), "html.parser").children:
            link = user_html.findChild("a")['href']
            if not re.search(r'^/[\w.]*/$', link):
                continue
            user_name = user_html.find_all(text=lambda text: bool(text))  # pylint: disable=unnecessary-lambda
            user = {
                "type": "instagram",
                "url": self.URL + link,
                "avatar": user_html.findChild("img")['src'],
                "nickname": user_name[0],
                "name": user_name[1] if len(user_name) > 1 else None,
                "attributes": []
            }
            res.append(user)

        return res

    def get_followers(self, nickname: str) -> List[dict]:
        self.logger.info("Get followers for '%s'", nickname)
        self.driver.get(f"{self.URL}/{nickname}/")

        followers_link = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, f"a[href='/{nickname}/followers/']"))
        )
        followers_link.click()

        while True:
            try:
                end_div = WebDriverWait(self.driver, 5).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "div[class='oMwYe']"))
                )
            except TimeoutException:
                break
            self.driver.execute_script("return arguments[0].scrollIntoView(true);", end_div)
            time.sleep(0.5)

        followers_list = []
        followers_block = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "ul[class='jSC57  _6xe7A']"))
        )
        for user_li_element in bs(followers_block.get_attribute('innerHTML'), "html.parser").find_all("li"):
            user_name = user_li_element.find_all(text=lambda text: bool(text))  # pylint: disable=unnecessary-lambda
            img = user_li_element.findChild("img")
            followers_list.append({
                "avatar": img['src'] if img is not None else None,
                "nickname": user_name[0],
                "name": user_name[2] if len(user_name) >= 4 else None,
            })
        return followers_list

# from .core import SocialMediaParserBase # wait until login loading # wait until loading result # get res # pylint: disable=unnecessary-lambda # pylint: disable=unnecessary-lambda