import sys
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget,
    QLineEdit, QComboBox, QFileDialog, QMessageBox
)
from yt_dlp import YoutubeDL
from yt_dlp.utils import DownloadError


class YoutubeDownloader(QMainWindow):
    def __init__(self):
        super().__init__()

        # UI 구성 요소 초기화
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('DeepTube :: 비공식 유튜브 다운로더')
        self.setGeometry(300, 300, 400, 200)

        # 메인 위젯 및 레이아웃 설정
        self.main_widget = QWidget(self)
        self.main_layout = QVBoxLayout(self.main_widget)
        self.setCentralWidget(self.main_widget)

        # 유튜브 링크 입력 필드
        self.url_input = QLineEdit(self)
        self.url_input.setPlaceholderText('유튜브 비디오 url를 넣으세요.')
        self.main_layout.addWidget(self.url_input)

        # 해상도 및 비디오 포맷 선택
        self.quality_input = QComboBox(self)
        self.quality_input.addItems(['360p', '480p', '720p', '1080p', '1440p', '2160p', 'best', 'worst'])
        self.main_layout.addWidget(self.quality_input)

        # 오디오 포맷 선택
        self.audio_format_input = QComboBox(self)
        # 여기에는 오디오 포맷 옵션이 들어가게 수정해야 할 수도 있습니다.
        self.audio_format_input.addItems(['best', 'aac', 'flac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav'])
        self.main_layout.addWidget(self.audio_format_input)

        # 다운로드 버튼
        self.download_button = QPushButton('다운로드', self)
        self.download_button.clicked.connect(self.start_download)
        self.main_layout.addWidget(self.download_button)

        self.show()

    def start_download(self):
        video_url = self.url_input.text().strip()
        if not video_url:
            QMessageBox.warning(self, 'Warning', '유튜브 링크를 입력해주세요.')
            return

        video_quality = self.quality_input.currentText()
        audio_format = self.audio_format_input.currentText()

        # 파일 저장 경로 대화상자 표시
        save_path, _ = QFileDialog.getSaveFileName(self, 'Save Video', '/', 'Video Files (*.mp4)')

        if save_path:
            if not save_path.endswith('.mp4'):
                save_path += '.mp4'
            self.download_video(video_url, video_quality, audio_format, save_path)
        else:
            QMessageBox.warning(self, 'Warning', '파일 저장 경로가 지정되지 않았습니다.')

    def download_video(self, video_url, video_quality, audio_format, save_path):
        # ‘best’로 선택되었을 경우에 적절한 처리
        quality = f'{video_quality}p' if video_quality != 'best' and not video_quality.endswith('p') else video_quality

        ydl_opts = {
            'format': f'bestvideo[height<={quality}]+bestaudio/best[ext=m4a]',
            'outtmpl': save_path,
            'merge_output_format': 'mp4',  # 병합 포맷 지정
        }

        try:
            with YoutubeDL(ydl_opts) as ydl:
                ydl.download([video_url])
            QMessageBox.information(self, 'Success', '다운로드가 완료되었습니다.')
        except DownloadError as e:
            QMessageBox.critical(self, 'Error', '다운로드 중 오류가 발생했습니다.\n' + str(e))
        except Exception as e:
            QMessageBox.critical(self, 'Error', '예상치 못한 오류가 발생했습니다.\n' + str(e))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = YoutubeDownloader()
    sys.exit(app.exec())