from PIL import Image
from io import BytesIO
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

import constants
import cv2
import math
import numpy as np
import os
import utility

def generateURL(lat: float, lon: float, zoom: int):
    return f"https://yandex.ru/maps/43/kazan/?l=sat&ll={lat}%2C{lon}&z={zoom}"

class YandexMap:
    initial_zoom: int
    initial_lat: float
    initial_lon: float

    def __init__(self, initial_lat=49.103814, initial_lon=55.794258, initial_zoom=10):
        self.initial_lat = initial_lat
        self.initial_lon = initial_lon
        self.initial_zoom = initial_zoom
        self.pixel_ratio = constants.YANDEX_PIXEL_RATIO[self.initial_zoom]

        options = webdriver.ChromeOptions()
        # options.add_experimental_option("detach", True)
        self.driver = webdriver.Chrome(options)
        self.driver.get(generateURL(initial_lat, initial_lon, initial_zoom))
        self.driver.maximize_window()
        sleep(2)

        # Закрытие левой панели
        action = ActionChains(self.driver)
        action.click(self.driver.find_element(By.CLASS_NAME, 'sidebar-toggle-button'))
        action.perform()

        self.driver.execute_script("arguments[0].remove();", self.driver.find_element(By.XPATH, "//div[@data-chunk='header']"))
        self.driver.execute_script("arguments[0].remove();", self.driver.find_element(By.XPATH, "//div[@class='sidebar-toggle-button _collapsed _name_home']"))
        self.driver.execute_script("arguments[0].remove();", self.driver.find_element(By.XPATH, "//nav[@class='map-controls']"))
        self.driver.execute_script("arguments[0].remove();", self.driver.find_element(By.XPATH, "//footer"))

        self.move(39, -9)

        sleep(0.2)

    def open(self, lat, lon, zoom):
        self.initial_lat = lat
        self.initial_lon = lon
        self.initial_zoom = zoom
        self.pixel_ratio = constants.YANDEX_PIXEL_RATIO[self.initial_zoom]
        self.driver.get(generateURL(lat, lon, zoom))
        sleep(2)

        # Закрытие левой панели
        action = ActionChains(self.driver)
        action.click(self.driver.find_element(By.CLASS_NAME, 'sidebar-toggle-button'))
        action.perform()

        self.move(39, -9)

    def save_photo(self, filename: str) -> bytes:
        return self.driver.save_screenshot(filename)

    def destroy(self):
        self.driver.close()
    
    def get_size(self) -> tuple[int, int]:
        html = self.driver.find_element(By.TAG_NAME, 'html')
        return (html.size['width'], html.size['height'])

    def scroll(self, x: float, y: float, count: int = 1, inner_zoom: bool = True):
        html = self.driver.find_element(By.TAG_NAME, 'html')

        x_offset = (x - 0.5) * html.size['width']
        y_offset = (y - 0.5) * html.size['height']
        action = ActionChains(self.driver)

        for i in range(count-1):
            action.scroll_from_origin(ScrollOrigin(html, int(x_offset), int(y_offset)), 0, -100 if inner_zoom else 100)
            action.perform()
            if i != count - 1:
                sleep(0.25)

    def move(self, dx: float, dy: float):
        html = self.driver.find_element(By.TAG_NAME, 'html')
        action = ActionChains(self.driver)
        action.move_to_element_with_offset(html, 0, 0)
        action.click_and_hold()
        action.move_by_offset(-dx, dy)
        action.release()
        action.perform()


    def make_as_center(self, x: float, y: float):
        dx = (x - 0.5) * self.get_size()[0]
        dy = (0.5 - y) * self.get_size()[1]
        self.move(dx, dy)

    def make_screenshot(self) -> Image.Image:
        png = self.driver.get_screenshot_as_png()
        im = Image.open(BytesIO(png))
        return utility.cv2_to_pil(np.array(im)[:, :])

    def get_geolocation(self):
        current_url = self.driver.current_url
        return utility.parse_yandex_maps_url(current_url)    
