import sys
import asyncio
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QLabel, 
                             QLineEdit, QPushButton, QComboBox, QTextEdit, QFileDialog, QHBoxLayout)
from PyQt5.QtCore import Qt
from playwright.async_api import async_playwright
from PyQt5.QtGui import QClipboard

class PlaywrightTester(QWidget):
    def __init__(self):
        super().__init__()

        # GUI 레이아웃 설정
        self.initUI()
        self.browser = None
        self.page = None
        self.elements = []  # 여러 요소를 찾을 때 저장하는 리스트
        self.current_element_index = 0  # 현재 확인 중인 요소 인덱스
        self.playwright = None
        self.log_file_path = None
        self.clipboard = QApplication.clipboard()

    def initUI(self):
        layout = QVBoxLayout()

        # 테스트할 URL 입력 필드
        self.url_input = QLineEdit(self)
        self.url_input.setPlaceholderText("Enter URL to test")
        self.url_input.setText("https://percenty.co.kr")
        layout.addWidget(self.url_input)

        # 선택자 타입 설명 라벨
        self.selector_type_label = QLabel("Selector Type (CSS, XPath, Name):")
        layout.addWidget(self.selector_type_label)

        # 선택자 타입 콤보박스 (CSS, XPath, Name)
        self.selector_type_combobox = QComboBox()
        self.selector_type_combobox.addItems(["CSS", "XPath", "Name"])
        self.selector_type_combobox.currentIndexChanged.connect(self.update_selector_input)
        layout.addWidget(self.selector_type_combobox)

        # 선택자 입력 필드
        self.selector_input = QLineEdit(self)
        self.selector_input.setPlaceholderText("Enter selector here (CSS, XPath, Name)")
        layout.addWidget(self.selector_input)

        # Playwright 실행 버튼
        self.playwright_button = QPushButton("Start Playwright", self)
        self.playwright_button.clicked.connect(self.start_playwright)
        layout.addWidget(self.playwright_button)

        # 요소 찾기 버튼
        self.find_button = QPushButton("Find Element", self)
        self.find_button.clicked.connect(self.find_element)
        layout.addWidget(self.find_button)

        # 요소 클릭 버튼
        self.click_button = QPushButton("Click Element", self)
        self.click_button.clicked.connect(self.click_element)
        layout.addWidget(self.click_button)

        # 다음 요소 확인 버튼 (여러 요소가 있을 때)
        self.next_element_button = QPushButton("Next Element", self)
        self.next_element_button.clicked.connect(self.show_next_element)
        layout.addWidget(self.next_element_button)

        # 선택자 복사 버튼
        self.copy_selector_button = QPushButton("Copy Selector", self)
        self.copy_selector_button.clicked.connect(self.copy_selector)
        layout.addWidget(self.copy_selector_button)

        # 로그 창 (출력 결과 표시)
        self.log_output = QTextEdit(self)
        self.log_output.setReadOnly(True)
        layout.addWidget(self.log_output)

        # 메인 레이아웃 설정
        self.setLayout(layout)
        self.setWindowTitle('Playwright Element Tester')
        self.setGeometry(300, 300, 400, 400)

    def log_message(self, message):
        """로그 출력 및 저장"""
        self.log_output.append(message)

    def update_selector_input(self):
        """선택자 타입에 따라 입력 필드를 업데이트"""
        selector_type = self.selector_type_combobox.currentText()
        if selector_type == "Name":
            self.selector_input.setPlaceholderText("Enter text to find elements by Name")
        else:
            self.selector_input.setPlaceholderText(f"Enter {selector_type} selector here")

    async def async_playwright_setup(self, url):
        """Playwright 비동기 실행 및 페이지 설정"""
        self.playwright = await async_playwright().start()
        self.browser = await self.playwright.chromium.launch(headless=False)
        
        # 페이지 생성 시 viewport 설정
        self.page = await self.browser.new_page(viewport={"width": 1920, "height": 1080})
        await self.page.goto(url)

    def start_playwright(self):
        """Playwright 실행"""
        url = self.url_input.text()
        if not url:
            self.log_message("URL을 입력하세요.")
            return
        
        self.log_message(f"Playwright 실행 중... URL: {url}")
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.async_playwright_setup(url))
        self.log_message("Playwright 실행 완료. 페이지 로드됨.")

    async def find_element_async(self):
        """요소 찾기 비동기 작업"""
        selector_type = self.selector_type_combobox.currentText()
        selector = self.selector_input.text()

        try:
            self.elements = []  # 요소 리스트 초기화
            if selector_type == "CSS":
                self.elements = await self.page.query_selector_all(selector)
            elif selector_type == "XPath":
                self.elements = await self.page.query_selector_all(selector)
            elif selector_type == "Name":
                # 이름을 기준으로 요소 찾기
                self.elements = await self.page.query_selector_all(f'[name="{selector}"]')

            if self.elements:
                self.current_element_index = 0
                self.log_message(f"요소 찾기 성공. 총 {len(self.elements)}개의 요소 발견.")
                await self.show_current_element_info()
            else:
                self.log_message(f"요소를 찾을 수 없음: {selector}")

        except Exception as e:
            self.log_message(f"오류 발생: {e}", exc_info=True)

    def find_element(self):
        """요소 찾기 동작"""
        self.log_message("요소 찾기 시작...")
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.find_element_async())

    async def show_current_element_info(self):
        """현재 선택된 요소의 정보를 표시"""
        if not self.elements:
            self.log_message("요소가 없습니다.")
            return
        
        current_element = self.elements[self.current_element_index]
        selector_type = self.selector_type_combobox.currentText()

        # 요소 정보 출력
        if selector_type == "CSS":
            element_info = await current_element.evaluate("e => e.outerHTML")
            self.log_message(f"요소 {self.current_element_index + 1}/{len(self.elements)} 정보: {element_info}")
        elif selector_type == "XPath":
            element_info = await current_element.evaluate("e => e.outerHTML")
            self.log_message(f"요소 {self.current_element_index + 1}/{len(self.elements)} 정보: {element_info}")
        elif selector_type == "Name":
            element_info = await current_element.evaluate("e => e.outerHTML")
            self.log_message(f"요소 {self.current_element_index + 1}/{len(self.elements)} 정보: {element_info}")

    def show_next_element(self):
        """다음 요소 확인"""
        if not self.elements:
            self.log_message("찾은 요소가 없습니다.")
            return

        self.current_element_index = (self.current_element_index + 1) % len(self.elements)
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.show_current_element_info())

    async def click_element_async(self):
        """요소 클릭 비동기 작업"""
        if not self.elements:
            self.log_message("요소가 없어서 클릭할 수 없습니다.")
            return

        try:
            current_element = self.elements[self.current_element_index]
            await current_element.click()
            self.log_message(f"요소 클릭 성공: {self.current_element_index + 1}/{len(self.elements)}")

        except Exception as e:
            self.log_message(f"클릭 오류 발생: {e}", exc_info=True)

    def click_element(self):
        """요소 클릭 동작"""
        self.log_message("요소 클릭 시작...")
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.click_element_async())

    def copy_selector(self):
        """현재 선택한 요소의 선택자를 클립보드로 복사"""
        if not self.elements:
            self.log_message("복사할 요소가 없습니다.")
            return

        selector = self.selector_input.text()
        self.clipboard.setText(selector)
        self.log_message(f"선택자 복사 완료: {selector}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = PlaywrightTester()
    ex.show()
    sys.exit(app.exec_())
