import sys
from PyQt5.QtWidgets import QSizePolicy, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QGridLayout
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
import requests
from PIL import Image
from io import BytesIO
import asyncio, aiofiles, aiohttp

class ResultWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
      
    def initUI(self):
        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)

    def show_results(self, results):

        try:
            # 결과 위젯 생성
            self.results_widget = QWidget()
            layout = QVBoxLayout()
            self.results_widget.setLayout(layout)

            # 결과 갯수 확인 및 레이아웃 동적 생성
            total_count = int(results['total_count'])
            set_count = min(total_count, 10)
            grid_layout = QGridLayout()
            layout.addLayout(grid_layout)
            grid_index = 0
            grid_columns = 5

            for i in range(1, set_count + 1):
                result_key = f"result_{i}"
                if result_key in results:
                    result = results[result_key]

                    # 테두리 설정
                    border_style = ''
                    if result['application_status'] == '등록':
                        border_style = 'border: 4px solid red;'
                    elif result['application_status'] == '공고':
                        border_style = 'border: 3px solid black;'
                        
                    # 각 결과에 대한 레이아웃 생성
                    item_layout = QVBoxLayout()
                    item_widget = QWidget()  # 위젯 생성

                    # item_layout의 크기 정책 설정
                    item_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

                    # 이미지 처리
                    image_label = QLabel()
                    image_label.setFixedSize(150, 150)
                    image_data = self.fetch_image_data(result['drawing_url'])
                    pixmap = QPixmap()
                    pixmap.loadFromData(image_data)
                    # QLabel의 크기에 맞게 이미지 크기 조정
                    scaled_pixmap = pixmap.scaled(image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
                    image_label.setPixmap(scaled_pixmap)
                    # QLabel의 가로 세로 중앙에 이미지 표시
                    image_label.setAlignment(Qt.AlignCenter)
                    # 이미지 표시 위젯의 크기 조정 정책 설정
                    image_label.setScaledContents(True)

                    #이미지 중앙배치를 위해
                    horizontal_layout = QHBoxLayout()
                    horizontal_layout.addWidget(image_label)
                    horizontal_layout.setAlignment(Qt.AlignCenter)
                    item_layout.addLayout(horizontal_layout)

                    # item_layout.addWidget(image_label)

                    # 정보 텍스트
                    # info_text = f"상표권명: {result['title']}\n등록상태: {result['admin_status']}\nCategory: {result['product_category']}\nApplicant: {result['applicant']}\nPublication Date: {result['publication_date']}\nRegistration Date: {result['registration_date']}"
                    info_text = f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>상표권명: {result['title']}</span><br>\n" \
                                f"<span style='font-size: 11pt; font-weight: bold; text-decoration: underline;'>등록상태: {result['application_status']}</span><br>\n" \
                                f"<span style='font-size: 9pt;'>카테고리: {result['product_category']}</span><br>\n" \
                                f"<span style='font-size: 9pt;'>권리자: {result['applicant_name']}</span><br>\n" \
                                f"<span style='font-size: 9pt;'> {result['publication_date']}</span><br>\n" \
                                f"<span style='font-size: 9pt;'> {result['registration_date']}</span>"

                    info_label = QLabel(info_text)
                    info_label.setToolTip(self.wrap_text(result['category_description'], 50))
                    image_label.setToolTip(self.wrap_text(result['category_description'], 50))
                    item_layout.addWidget(info_label)

                    image_label.setStyleSheet(border_style)
                    info_label.setStyleSheet(border_style)

                    # 레이아웃에 위젯 추가
                    row = grid_index // grid_columns
                    col = grid_index % grid_columns
                    grid_layout.addLayout(item_layout, row, col)
                    grid_index += 1

            # 결과 위젯에 닫기 버튼 추가
            close_button = QPushButton("Close")
            close_button.clicked.connect(self.close_results_widget)
            layout.addWidget(close_button)

            # 결과 위젯을 메인 윈도우에 추가
            self.results_widget.setGeometry(300, 300, 600, 300)  # 위치와 크기 설정
            self.results_widget.setWindowTitle('Search Results')  # 타이틀 설정
            self.results_widget.show()

        except Exception as e:
            print(f"Error displaying results: {e}")


    def close_results_widget(self):
        # 결과 위젯닫기 함수를 호출할 때 사용하는 메서드
        self.results_widget.close()


    def wrap_text(self, text, width=40):
        """주어진 너비에 맞게 텍스트를 줄바꿈합니다."""
        words = text.split()
        wrapped_text = ''
        line_length = 0

        for word in words:
            if line_length + len(word) + 1 > width:
                wrapped_text += '\n'
                line_length = 0
            wrapped_text += word + ' '
            line_length += len(word) + 1

        return wrapped_text.strip()


    async def fetch_image_data_async(self, url):
        """주어진 URL로부터 이미지 데이터를 비동기적으로 가져와 반환합니다."""
        async with aiohttp.ClientSession() as session:
            # print(f"download_image session Start!!")
            async with session.get(url) as response:
                print(f"download_image url : {url}")
                if response.status == 200:
                    # print(f"response : {response}")
                    content_type = response.headers.get('Content-Type', '')  # await 제거
                    print(f"content_type : {content_type}")
                    if 'image' in content_type or 'octet-stream' in content_type:
                        # print(f"image content type or octet-stream : {content_type}")
                        return await response.read()
                    else:
                        try:
                            # Content-Type이 이미지가 아니면, 데이터를 이미지로 변환
                            data = await response.read()
                            # print(f"Content-Type이 이미지가 아님 : {data}")
                            image = Image.open(BytesIO(data))
                            with BytesIO() as buffer:
                                image.save(buffer, 'JPEG')
                                print(f"image 를 JPEG로 저장")
                                return buffer.getvalue()
                        except Exception as e:
                            print(f"이미지 변환 실패: {e}")
                            return None
                else:
                    print(f"이미지 다운로드 실패: HTTP {response.status}")
                    return None


    def fetch_image_data(self, url):
        """주어진 URL로부터 이미지 데이터를 가져와 반환합니다."""
        response = requests.get(url)
        if response.status_code == 200:
            # 서버 응답 헤더에서 Content-Type 확인
            content_type = response.headers.get('Content-Type', '')
            if 'image' in content_type:
                return response.content
            else:
                # Content-Type이 이미지가 아니면, 데이터를 이미지로 변환
                try:
                    image = Image.open(BytesIO(response.content))
                    with BytesIO() as buffer:
                        image.save(buffer, 'JPEG')  # 예시로 JPEG 포맷을 사용
                        return buffer.getvalue()
                except Exception as e:
                    print(f"이미지 변환 실패: {e}")
                    return None
        else:
            print(f"이미지 다운로드 실패: HTTP {response.status_code}")
            return None
