import os
import tempfile
from datetime import datetime

class OptionHandler:
    def __init__(self, page, whale_translator, logger, vertexAI, debug=False):
        self.page = page
        self.logger = logger
        self.debug = debug
        self.vertexAItranslator = vertexAI
        self.whale_translator = whale_translator
        self.option_info = {
            'original_names': {},
            'edit_fields': {},
            'checkboxes': [],
            'images': {},
            'prices': {}  # 가격 정보 추가
        }

    def update_page(self, page1):
        self.page = page1
        self.logger.debug(f"page객체 업데이트 : {page1}")

    async def process_options(self, product_name, max_option_count=10):
        """
        옵션 처리 로직. 옵션을 번역하고 이미지를 업데이트함.

        :param product_name: 상품명 (str 형태).
        :param max_option_count: 최대 옵션 갯수 (기본값 10).
        """
        try:
            self.logger.debug(f"상품명: {product_name}에 대한 옵션을 처리 중...")

            # 1. 단일 옵션인지 판단
            if self.is_single_option():
                self.logger.debug("단일 옵션 상품입니다. 옵션 수정 과정을 생략합니다.")
                return
            
            # 2. 전체 옵션 체크박스 상태 확인
            if not self.is_all_options_checked():
                self.logger.debug("옵션이 일부만 체크된 상태입니다. 옵션 수정이 완료된 상품으로 판단하여 패스합니다.")
                return
            
            # 3. 가격 낮은 순 정렬 클릭
            await self.low_order_click()
            
            # 4. 옵션 정보 수집 및 번역
            self.option_info = await self.collect_options_info()

            # Vertex AI를 통해 옵션명을 번역
            translated_options = await self.vertexAItranslator.translate_options(self.option_info['original_names'], product_name)
            self.logger.debug(f"번역된 옵션: {translated_options}")

            # 5. 번역된 옵션명 편집칸에 입력
            self.logger.debug("번역된 옵션명을 입력합니다.")
            await self.apply_translated_options(translated_options, self.option_info['edit_fields'])

            # 6. 옵션 이미지 업데이트 (옵션 이미지가 있는 경우)
            self.logger.debug("옵션 이미지 업데이트 (옵션 이미지가 있는 경우)")
            for index, option_image_url in enumerate(self.option_info.get('option_images', []), start=1):
                option_name = translated_options.get(f'trans_option_{index}', f'옵션_{index}')
                await self.update_option_image(index, option_image_url, product_name, option_name, self.debug)

            # 7. 옵션 선택 및 제한 처리
            await self.adjust_options(self.option_info['checkboxes'], max_option_count)

            # 8. 정리된 옵션을 다시한번 더 가격 낮은 순으로 정렬 클릭
            await self.low_order_click()

            # 9. 저장 버튼 클릭
            self.logger.debug("저장 버튼을 클릭합니다.")
            await self.page.click('button:has-text("저장하기")')

            self.logger.debug("옵션 처리 완료.")

        except Exception as e:
            self.logger.debug(f"옵션 처리 중 오류 발생: {e}", exc_info=True)
            return

    def is_single_option(self):
        """단일 상품 상태 여부를 확인하는 메서드"""
        try:
            # 단일 상품 등록 버튼이 선택되었는지 확인
            single_option_xpath = "//div[@id='productMainContentContainerId']//label[contains(@class, 'ant-radio-button-wrapper-checked') and contains(., '단일 상품등록')]"
            single_option_checked = self.page.query_selector(single_option_xpath) is not None

            # 옵션 상품 등록 버튼이 선택되었는지 확인
            option_product_xpath = "//div[@id='productMainContentContainerId']//label[contains(@class, 'ant-radio-button-wrapper-checked') and contains(., '옵션 상품등록')]"
            option_product_checked = self.page.query_selector(option_product_xpath) is not None

            # 두 요소의 상태를 기반으로 단일 상품 여부 결정
            is_single = single_option_checked and not option_product_checked
            self.logger.debug(f"단일 상품 여부: {'단일 상품입니다' if is_single else '옵션 상품입니다'}")
            return is_single
        except Exception as e:
            self.logger.error(f"단일 옵션 확인 중 예외 발생: {e}", exc_info=True)
            return False


    def is_all_options_checked(self):
        """전체 옵션 체크박스 상태를 확인 (전체 체크 여부)"""
        try:
            checkbox = self.page.query_selector('#productMainContentContainerId .ant-checkbox-wrapper-checked')
            if checkbox:
                self.logger.debug("전체 옵션이 체크되어 있음")
                return True
            checkbox_partial = self.page.query_selector('#productMainContentContainerId .ant-checkbox-indeterminate')
            self.logger.debug("일부 옵션이 체크되어 있으므로 수정완료 상품으로 판단.")
            return checkbox_partial is None  # 일부 체크 시 False
        except Exception as e:
            self.logger.error(f"전체 옵션 체크박스 확인 중 오류 발생: {e}", exc_info=True)
            return False

    async def collect_options_info(self):
        """옵션 정보를 수집 (이미지, 옵션명, 편집 필드, 가격, 체크박스 정보 포함)"""
        # option_info = {
        #     'original_names': {},
        #     'edit_fields': {},
        #     'checkboxes': [],
        #     'images': {},
        #     'prices': {}  # 가격 정보 추가
        # }

        try:
            # 총 옵션 갯수 수집
            total_options_selector = '#productMainContentContainerId label.ant-checkbox-wrapper'
            total_options_element = await self.page.query_selector(total_options_selector)
            if total_options_element:
                total_options_text = await total_options_element.inner_text()
                total_options_count = int(''.join(filter(str.isdigit, total_options_text)))  # 숫자만 추출
            else:
                total_options_count = 0  # 옵션 갯수를 찾지 못할 경우 기본값

            self.logger.debug(f"총 옵션 갯수: {total_options_count}")

            # 옵션 정보를 수집 (총 옵션 갯수만큼 반복)
            for i in range(1, total_options_count + 1):
                try:
                    # 원본옵션명 수집
                    original_name_selector = f"div#productMainContentContainerId li:nth-child({i}) > div > div:nth-child(1) > div > div:nth-child(3) > div:nth-child(3) > span"
                    original_name_element = await self.page.query_selector(original_name_selector)
                    original_name = await original_name_element.inner_text() if original_name_element else None

                    if original_name:
                        # 옵션명 기준으로 수집 항목 구성
                        self.logger.debug(f"{i}번째 옵션명 수집완료. 나머지 필드 수집중...")
                        self.option_info['original_names'][f'origin_option_{i}'] = original_name

                        # 옵션 편집 필드 수집
                        edit_field_selector = f"div#productMainContentContainerId li:nth-child({i}) > div > div:nth-child(1) > div > div:nth-child(3) > div:nth-child(2) > div:nth-child(1) > span > input"
                        edit_field_element = await self.page.query_selector(edit_field_selector)
                        if edit_field_element:
                            self.option_info['edit_fields'][original_name] = edit_field_element
                            self.logger.debug(f"{i}번째 옵션편집필드 수집 완료 : {edit_field_element}")
                        else:
                            self.logger.debug(f"{i}번째 옵션편집필드 수집 실패▣ edit_field_element : {edit_field_element}")
                            

                        # 옵션 체크박스 수집
                        checkbox_selector = f'#productMainContentContainerId li:nth-child({i}) input[type="checkbox"]'
                        # f"div#productMainContentContainerId li:nth-child({i}) > div > div:nth-child(1) > div > div:nth-child(1) > label > span > input"
                        checkbox_element = await self.page.query_selector(checkbox_selector)
                        if checkbox_element:
                            self.option_info['checkboxes'].append(checkbox_element)
                            self.logger.debug(f"{i}번째 옵션 체크박스 수집 완료 : {checkbox_element}")
                        else:
                            self.logger.debug(f"{i}번째 옵션 체크박스 수집 실패▣ checkbox_element : {checkbox_element}")

                        # 옵션 이미지 수집
                        image_selector = f'#productMainContentContainerId li:nth-child({i}) img.sc-gbvfcU.ezktkd'
                        # "div#productMainContentContainerId li:nth-child(1) > div > div:nth-child(1) > div > div:nth-child(2) > div > img"
                        # "div#productMainContentContainerId li:nth-child(2) > div > div:nth-child(1) > div > div:nth-child(2) > div > img"
                        image_element = await self.page.query_selector(image_selector)
                        if image_element:
                            image_url = await image_element.get_attribute('src')
                            self.option_info['images'][original_name] = image_url
                            self.logger.debug(f"{i}번째 옵션 이미지 수집 완료 : {image_element}")
                        else:
                            self.option_info['images'][original_name] = None  # 이미지가 없으면 None.
                            self.logger.debug(f"{i}번째 옵션 이미지 수집 실패▣ image_element : {image_element}")

                        # 가격 정보 수집
                        price_selector = f'#productMainContentContainerId li:nth-child({i}) sup'
                        price_element = await self.page.query_selector(price_selector)
                        if price_element:
                            price_text = await price_element.inner_text()
                            price_text = price_text.replace(",", "").replace("원", "").strip()

                            if " - " in price_text:
                                low_price, high_price = map(int, price_text.split(" - "))
                            else:
                                low_price = high_price = int(price_text)
                            self.option_info['prices'][original_name] = {'low_price': low_price, 'high_price': high_price}

                            self.logger.debug(f"{i}번째 옵션 가격정보 수집 완료 : {low_price} - {high_price}")
                        else:
                            self.logger.debug(f"{i}번째 옵션 가격정보 수집 실패▣ price_element : {price_element}")


                except Exception as e:
                    self.logger.error(f"{i}번째 옵션 수집 중 오류 발생: {e}", exc_info=True)

        except Exception as e:
            self.logger.error(f"옵션 정보 수집 중 오류 발생: {e}", exc_info=True)

        return self.option_info

    async def apply_translated_options(self, translated_options, edit_fields):
        """번역된 옵션명을 편집 필드에 입력"""
        try:
            # translated_options = await translated_options  # 코루틴 실행 후 결과를 저장
            for key, translated_name in translated_options.items():
                self.logger.debug(f"{key}번째 translated_name : {translated_name}")
                
                # 원본 옵션명을 기준으로 참조
                origin_option_key = key.replace('trans_', 'origin_')  # 'trans_option_1'을 'origin_option_1'로 변환
                original_name = self.option_info['original_names'].get(origin_option_key)

                if original_name:
                    edit_field = edit_fields.get(original_name)  # 원본 옵션명으로 필드 참조
                    self.logger.debug(f"{key}번째 번역옵션 필드 : {edit_field}")
                    
                    if edit_field:
                        await edit_field.fill(translated_name)  # 필드에 번역된 옵션명 입력
                        self.logger.debug(f"{key}번째 translated_name : [{translated_name}] 입력 완료")
                    else:
                        self.logger.debug(f"{key}번째 옵션 필드가 없습니다.")
                else:
                    self.logger.debug(f"원본 옵션명을 찾을 수 없습니다: {origin_option_key}")
        except Exception as e:
            self.logger.error(f"번역된 옵션명을 입력하는 중 오류 발생: {e}", exc_info=True)

    async def adjust_options(self, checkboxes, max_option_count):
        """옵션 체크 상태 조정"""
        try:
            if len(checkboxes) > 3:
                self.logger.debug("옵션이 3개 이상이므로 가장 낮은 옵션을 체크 해제합니다.")
                await checkboxes[0].click()
            
            if len(checkboxes) > max_option_count:
                self.logger.debug("옵션이 10개 이상이므로 초과 옵션을 체크 해제합니다.")
                for i in range(max_option_count, len(checkboxes)):
                    await checkboxes[i].click()
        except Exception as e:
            self.logger.error(f"옵션 체크 조정 중 오류 발생: {e}", exc_info=True)

    async def check_options(self, option_info):
        """옵션 체크 로직: 모든 옵션 체크 해제 후 다시 선택"""
        try:
            # 전체 옵션 체크박스 체크 해제
            total_checkbox_selector = '#productMainContentContainerId label.ant-checkbox-wrapper'
            total_checkbox_element = await self.page.query_selector(total_checkbox_selector)
            if total_checkbox_element:
                await total_checkbox_element.click()
                self.logger.debug("모든 옵션 체크 해제 완료")

            # 옵션 갯수에 따라 선택 로직 진행
            total_options_count = len(self.option_info['original_names'])
            self.logger.debug(f"선택 가능한 옵션 수: {total_options_count}")

            if total_options_count > 2:
                # 3개 이상인 경우: 1번째 옵션을 제외하고 최대 10개까지만 체크
                options_to_check = self.option_info['checkboxes'][1:self.max_selected_options + 1]
            else:
                # 2개 이하인 경우: 모두 체크
                options_to_check = self.option_info['checkboxes']

            # 선택된 옵션들 체크
            for checkbox in options_to_check:
                await checkbox.click()
                self.logger.debug(f"옵션 체크 완료: {checkbox}")

        except Exception as e:
            self.logger.error(f"옵션 체크 중 오류 발생: {e}", exc_info=True)

    async def low_order_click(self):
        self.logger.debug("가격 낮은 순 정렬을 클릭합니다.")
        await self.page.click('button:has-text("가격 낮은 순")')
        await self.page.wait_for_load_state('domcontentloaded')

    async def save_option(self):
        """옵션 수정 후 저장 버튼 클릭"""
        try:
            await self.page.click('button:has-text("저장하기")')
            self.logger.debug("옵션 수정 내용 저장 완료.")
        except Exception as e:
            self.logger.debug(f"옵션수정 후 저장 버튼 클릭 중 오류: {e}", exc_info=True)


    # async def update_option_image(self, option_index, option_image_url, product_name, option_name, debug=False):
    #     """옵션 이미지가 존재할 경우 삭제 후, 새로운 번역된 이미지를 추가하는 메서드"""
    #     try:
    #         image_css = f"#productMainContentContainerId > div.sc-TOgAA.fZvEqY > div:nth-child(2) > div > div > div:nth-child(2) > div > div.sc-cFShuL.dbIeho > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-fGdiLE.iyXMeU > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li:nth-child({option_index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > img"
    #         delete_button_css = f"#productMainContentContainerId > div.sc-TOgAA.fZvEqY > div:nth-child(2) > div > div > div:nth-child(2) > div > div.sc-cFShuL.dbIeho > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-fGdiLE.iyXMeU > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li:nth-child({option_index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div.ant-row.ant-row-no-wrap.ant-row-space-between.ant-row-middle.css-1li46mu > div:nth-child(1) > div"
    #         add_button_css = f"#productMainContentContainerId > div.sc-TOgAA.fZvEqY > div:nth-child(2) > div > div > div:nth-child(2) > div > div.sc-cFShuL.dbIeho > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-fGdiLE.iyXMeU > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li:nth-child({option_index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div > img"

    #         # 옵션 이미지가 있는지 확인하고, 있으면 삭제
    #         option_image_element = await self.page.locator(image_css).element_handle()
    #         if option_image_element:
    #             self.logger.debug(f"{option_index}번째 옵션 이미지가 존재합니다. 삭제 버튼을 클릭합니다.")
    #             delete_button_element = await self.page.locator(delete_button_css).element_handle()

    #             if delete_button_element:
    #                 await delete_button_element.click()
    #                 self.logger.debug(f"{option_index}번째 옵션 이미지 삭제 버튼 클릭 완료.")

    #                 # 삭제 확인 버튼 클릭
    #                 confirm_button_css = 'body > div:nth-child(18) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.sc-ddjGPC.jbwEYW > div > div > div > div.ant-modal-confirm-btns > button.ant-btn.css-1li46mu.ant-btn-primary.ant-btn-dangerous'
    #                 confirm_button = await self.page.locator(confirm_button_css).element_handle()
    #                 if confirm_button:
    #                     await confirm_button.click()
    #                     self.logger.debug(f"{option_index}번째 옵션 이미지 삭제 확인 완료.")

    #         else:
    #             self.logger.debug(f"{option_index}번째 옵션 이미지는 존재하지 않습니다. 바로 추가 작업을 진행합니다.")

    #         # 이미지 추가 버튼 클릭
    #         add_button_element = await self.page.locator(add_button_css).element_handle()
    #         if add_button_element:
    #             await add_button_element.click()
    #             self.logger.debug(f"{option_index}번째 옵션 이미지 추가 버튼 클릭 완료.")

    #             # 파일 저장 경로 생성
    #             current_time = datetime.now().strftime('%Y%m%d_%H%M%S')
    #             tmp_image_dir = os.path.join(os.getcwd(), 'tmp_image')
    #             os.makedirs(tmp_image_dir, exist_ok=True)  # 디렉토리 생성
    #             temp_image_path = os.path.join(tmp_image_dir, f'{product_name}_{option_name}_{current_time}.png')

    #             # 옵션 이미지 번역 후 파일 추가
    #             translated_image_path = await self.whale_translator.translate_image(option_image_url, path=temp_image_path)
    #             self.logger.debug(f"{option_index}번째 옵션 번역된 이미지 경로: {translated_image_path}")

    #             # 파일 선택 다이얼로그에 번역된 이미지 경로 입력
    #             await self.page.set_input_files('input[type="file"]', translated_image_path)
    #             self.logger.debug(f"{option_index}번째 옵션에 번역된 이미지 파일이 추가되었습니다.")

    #             # 번역된 이미지가 성공적으로 업로드되었으면 임시 파일 삭제
    #             if not debug:
    #                 if os.path.exists(translated_image_path):
    #                     os.remove(translated_image_path)
    #                     self.logger.debug(f"임시 파일 {translated_image_path}이(가) 삭제되었습니다.")

    #     except Exception as e:
    #         self.logger.error(f"{option_index}번째 옵션 이미지 처리 중 오류 발생: {e}", exc_info=True)

    async def update_option_image(self, index, option_image_url, product_name, option_name, debug=False):
        """
        옵션 이미지가 존재할 경우, 기존 이미지를 삭제하고 번역된 이미지를 추가하는 메서드.
        
        :param index: 옵션 인덱스.
        :param option_image_url: 옵션 이미지 URL.
        :param product_name: 상품명.
        :param option_name: 옵션명.
        :param debug: 디버그 모드일 경우 이미지를 삭제하지 않음 (기본값 False).
        """
        try:
            # 이미지가 없을 경우 메서드 종료
            if not option_image_url:
                self.logger.debug(f"{index}번째 옵션의 이미지가 존재하지 않아 작업을 종료합니다.")
                return

            self.logger.debug(f"{index}번째 옵션의 이미지를 업데이트합니다.")

            # 기존 이미지 삭제 (삭제 버튼이 존재할 경우)
            delete_button_selector = f"#productMainContentContainerId > div.sc-TOgAA.fZvEqY > div:nth-child(2) > div > div > div:nth-child(2) > div > div.sc-cFShuL.dbIeho > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-fGdiLE.iyXMeU > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li:nth-child({index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div.ant-row.ant-row-no-wrap.ant-row-space-between.ant-row-middle.css-1li46mu > div:nth-child(1) > div"
            delete_button = await self.page.locator(delete_button_selector).element_handle()

            if delete_button:
                self.logger.debug(f"{index}번째 옵션의 기존 이미지를 삭제합니다.")
                await delete_button.click()

                # 삭제 확인 버튼 클릭
                confirm_delete_button_selector = "body > div:nth-child(18) > div > div.ant-modal-wrap.ant-modal-confirm-centered.ant-modal-centered > div > div.sc-ddjGPC.jbwEYW > div > div > div > div.ant-modal-confirm-btns > button.ant-btn.css-1li46mu.ant-btn-primary.ant-btn-dangerous"
                confirm_delete_button = await self.page.locator(confirm_delete_button_selector).element_handle()
                if confirm_delete_button:
                    await confirm_delete_button.click()
                    self.logger.debug(f"{index}번째 옵션의 이미지가 삭제되었습니다.")
                else:
                    self.logger.debug(f"삭제 확인 버튼을 찾을 수 없습니다.")

            # 이미지 번역 후 추가
            translated_image_path = await self.whale_translator.translate_image(option_image_url, f"tmp_image/{product_name}-{option_name}-{index}.png")
            
            # 이미지 업로드 버튼 클릭 (옵션 이미지가 없는 경우)
            add_button_selector = f"#productMainContentContainerId > div.sc-TOgAA.fZvEqY > div:nth-child(2) > div > div > div:nth-child(2) > div > div.sc-cFShuL.dbIeho > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-fGdiLE.iyXMeU > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li:nth-child({index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div > img"
            add_button = await self.page.locator(add_button_selector).element_handle()

            if add_button:
                await add_button.click()

                # 파일 선택 다이얼로그에서 번역된 이미지 파일 입력
                file_input = await self.page.wait_for_selector('input[type="file"]')
                await file_input.set_input_files(translated_image_path)
                self.logger.debug(f"{index}번째 옵션에 번역된 이미지가 추가되었습니다.")

                # 디버그 모드가 아닐 경우, 성공적으로 업로드 후 임시 파일 삭제
                if not debug:
                    import os
                    if os.path.exists(translated_image_path):
                        os.remove(translated_image_path)
                        self.logger.debug(f"번역된 이미지 파일이 삭제되었습니다: {translated_image_path}")

        except Exception as e:
            self.logger.error(f"{index}번째 옵션 이미지 업데이트 중 오류 발생: {e}", exc_info=True)
