# ui/main_window.py
import sys
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
    QTableWidget, QTableWidgetItem, QPushButton, QTabWidget,
    QLabel, QLineEdit, QComboBox, QSpinBox, QMessageBox,
    QDialog, QFormLayout, QDialogButtonBox, QHeaderView,
    QToolBar, QStatusBar, QGroupBox, QTextEdit, QInputDialog
)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
from PyQt6.QtGui import QAction, QIcon, QFont
from typing import Optional, Dict, Any
import logging

# Импортируем наш модуль БД
from database import Database

logger = logging.getLogger(__name__)

# Маппинг валют по регионам
CURRENCY_MAP = {
    'Pakistan': ('PKR', '₨'),
    'India': ('INR', '₹'),
    'China': ('CNY', '¥'),
    'USA': ('USD', '$'),
    'Dubai': ('AED', 'د.إ')
}

class ModelDialog(QDialog):
    """Диалог для добавления/редактирования модели"""
    
    def __init__(self, parent=None, model_data=None):
        super().__init__(parent)
        self.model_data = model_data
        self.db = Database()
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle("Добавить модель" if not self.model_data else "Редактировать модель")
        self.setModal(True)
        self.setMinimumWidth(500)
        
        layout = QFormLayout()
        
        # Поля формы
        self.company_combo = QComboBox()
        companies = self.db.get_all_companies()
        for company in companies:
            self.company_combo.addItem(company['company_name'], company['company_id'])
        
        self.model_name_edit = QLineEdit()
        self.weight_edit = QLineEdit()
        self.ram_edit = QLineEdit()
        self.front_camera_edit = QLineEdit()
        self.back_camera_edit = QLineEdit()
        self.processor_edit = QLineEdit()
        self.battery_edit = QLineEdit()
        self.screen_edit = QLineEdit()
        self.year_spin = QSpinBox()
        self.year_spin.setRange(2000, 2030)
        self.year_spin.setValue(2024)
        
        # Добавляем поля в форму
        layout.addRow("Компания:", self.company_combo)
        layout.addRow("Название модели:", self.model_name_edit)
        layout.addRow("Вес:", self.weight_edit)
        layout.addRow("RAM:", self.ram_edit)
        layout.addRow("Фронтальная камера:", self.front_camera_edit)
        layout.addRow("Основная камера:", self.back_camera_edit)
        layout.addRow("Процессор:", self.processor_edit)
        layout.addRow("Батарея:", self.battery_edit)
        layout.addRow("Размер экрана:", self.screen_edit)
        layout.addRow("Год выпуска:", self.year_spin)
        
        # Заполняем данные при редактировании
        if self.model_data:
            self.model_name_edit.setText(self.model_data.get('model_name', ''))
            self.weight_edit.setText(self.model_data.get('mobile_weight', ''))
            self.ram_edit.setText(self.model_data.get('ram', ''))
            self.front_camera_edit.setText(self.model_data.get('front_camera', ''))
            self.back_camera_edit.setText(self.model_data.get('back_camera', ''))
            self.processor_edit.setText(self.model_data.get('processor_name', ''))
            self.battery_edit.setText(self.model_data.get('battery_capacity', ''))
            self.screen_edit.setText(self.model_data.get('screen_size', ''))
            if self.model_data.get('launched_year'):
                self.year_spin.setValue(self.model_data['launched_year'])
            
            # Устанавливаем компанию
            for i in range(self.company_combo.count()):
                if self.company_combo.itemData(i) == self.model_data.get('company_id'):
                    self.company_combo.setCurrentIndex(i)
                    break
        
        # Кнопки
        buttons = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | 
            QDialogButtonBox.StandardButton.Cancel
        )
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        
        layout.addRow(buttons)
        self.setLayout(layout)
    
    def get_data(self) -> Dict[str, Any]:
        """Получение данных из формы"""
        return {
            'company_id': self.company_combo.currentData(),
            'model_name': self.model_name_edit.text(),
            'mobile_weight': self.weight_edit.text() or None,
            'ram': self.ram_edit.text() or None,
            'front_camera': self.front_camera_edit.text() or None,
            'back_camera': self.back_camera_edit.text() or None,
            'processor_name': self.processor_edit.text() or None,
            'battery_capacity': self.battery_edit.text() or None,
            'screen_size': self.screen_edit.text() or None,
            'launched_year': self.year_spin.value()
        }


class PriceDialog(QDialog):
    """Диалог для управления ценами модели"""
    
    def __init__(self, parent=None, model_id=None, model_name=""):
        super().__init__(parent)
        self.model_id = model_id
        self.model_name = model_name
        self.db = Database()
        self.init_ui()
        self.load_prices()
        
    def init_ui(self):
        self.setWindowTitle(f"Цены для: {self.model_name}")
        self.setModal(True)
        self.setMinimumSize(600, 400)
        
        layout = QVBoxLayout()
        
        # Таблица цен
        self.prices_table = QTableWidget()
        self.prices_table.setColumnCount(4)
        self.prices_table.setHorizontalHeaderLabels(["Регион", "Цена", "Валюта", "Действия"])
        self.prices_table.setSortingEnabled(True)
        
        # Настройка размеров столбцов
        header = self.prices_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch)
        
        layout.addWidget(self.prices_table)
        
        # Форма добавления цены
        add_group = QGroupBox("Добавить/Обновить цену")
        add_layout = QHBoxLayout()
        
        self.region_combo = QComboBox()
        regions = self.db.get_all_regions()
        for region in regions:
            self.region_combo.addItem(region['region_name'], region['region_id'])
        
        self.price_edit = QLineEdit()
        self.price_edit.setPlaceholderText("Цена")
        
        add_btn = QPushButton("Добавить/Обновить")
        add_btn.clicked.connect(self.add_update_price)
        
        add_layout.addWidget(QLabel("Регион:"))
        add_layout.addWidget(self.region_combo)
        add_layout.addWidget(QLabel("Цена:"))
        add_layout.addWidget(self.price_edit)
        add_layout.addWidget(add_btn)
        
        add_group.setLayout(add_layout)
        layout.addWidget(add_group)
        
        # Кнопка закрытия
        close_btn = QPushButton("Закрыть")
        close_btn.clicked.connect(self.close)
        layout.addWidget(close_btn)
        
        self.setLayout(layout)
    
    def format_price(self, price: float, region_name: str) -> str:
        """Форматирование цены с правильным символом валюты"""
        currency_code, currency_symbol = CURRENCY_MAP.get(region_name, ('USD', '$'))
        return f"{currency_symbol}{price:,.2f}"
    
    def load_prices(self):
        """Загрузка цен из БД"""
        prices = self.db.get_model_prices(self.model_id)
        self.prices_table.setRowCount(len(prices))
        
        for row, price_data in enumerate(prices):
            # Регион
            region_item = QTableWidgetItem(price_data['region_name'])
            region_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.prices_table.setItem(row, 0, region_item)
            
            # Цена с правильной валютой
            price_str = self.format_price(price_data['price'], price_data['region_name'])
            price_item = QTableWidgetItem(price_str)
            price_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.prices_table.setItem(row, 1, price_item)
            
            # Код валюты
            currency_code, _ = CURRENCY_MAP.get(price_data['region_name'], ('USD', '$'))
            currency_item = QTableWidgetItem(currency_code)
            currency_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.prices_table.setItem(row, 2, currency_item)
            
            # Кнопка удаления
            delete_btn = QPushButton("Удалить")
            delete_btn.clicked.connect(lambda checked, pid=price_data['price_id']: self.delete_price(pid))
            self.prices_table.setCellWidget(row, 3, delete_btn)
    
    def add_update_price(self):
        """Добавление или обновление цены"""
        try:
            region_id = self.region_combo.currentData()
            price = float(self.price_edit.text())
            
            self.db.add_or_update_price(self.model_id, region_id, price)
            self.load_prices()
            self.price_edit.clear()
            
            QMessageBox.information(self, "Успех", "Цена успешно обновлена!")
        except ValueError:
            QMessageBox.warning(self, "Ошибка", "Введите корректную цену!")
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Ошибка при обновлении цены: {str(e)}")
    
    def delete_price(self, price_id):
        """Удаление цены"""
        reply = QMessageBox.question(
            self, "Подтверждение",
            "Вы уверены, что хотите удалить эту цену?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            try:
                self.db.delete_price(price_id)
                self.load_prices()
                QMessageBox.information(self, "Успех", "Цена удалена!")
            except Exception as e:
                QMessageBox.critical(self, "Ошибка", f"Ошибка при удалении: {str(e)}")


class MainWindow(QMainWindow):
    """Главное окно приложения"""
    
    def __init__(self):
        super().__init__()
        self.db = Database()
        self.init_ui()
        self.connect_to_db()
        
    def init_ui(self):
        self.setWindowTitle("Датасет мобильных устройств")
        self.setGeometry(100, 100, 1200, 600)
        
        # Центральный виджет
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # Основной layout
        layout = QVBoxLayout(central_widget)
        
        # Создаем панель инструментов
        self.create_toolbar()
        
        # Создаем вкладки
        self.tabs = QTabWidget()
        
        # Вкладка компаний
        self.companies_tab = self.create_companies_tab()
        self.tabs.addTab(self.companies_tab, "🏢 Компании")
        
        # Вкладка моделей
        self.models_tab = self.create_models_tab()
        self.tabs.addTab(self.models_tab, "📱 Модели")
        
        # Вкладка аналитики
        self.analytics_tab = self.create_analytics_tab()
        self.tabs.addTab(self.analytics_tab, "📊 Аналитика")
        
        layout.addWidget(self.tabs)
        
        # Статусная строка
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage("Готов к работе")
        
    def create_toolbar(self):
        """Создание панели инструментов"""
        toolbar = QToolBar()
        self.addToolBar(toolbar)
        
        # Действия
        refresh_action = QAction("🔄 Обновить", self)
        refresh_action.triggered.connect(self.refresh_data)
        toolbar.addAction(refresh_action)
        
        toolbar.addSeparator()
        
        add_company_action = QAction("➕ Добавить компанию", self)
        add_company_action.triggered.connect(self.add_company)
        toolbar.addAction(add_company_action)
        
        toolbar.addSeparator()
        
        add_model_action = QAction("➕ Добавить модель", self)
        add_model_action.triggered.connect(self.add_model)
        toolbar.addAction(add_model_action)
        
    def create_companies_tab(self) -> QWidget:
        """Создание вкладки компаний"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # Панель управления
        control_panel = QHBoxLayout()
        control_panel.addStretch()
        layout.addLayout(control_panel)
        
        # Таблица компаний
        self.companies_table = QTableWidget()
        self.companies_table.setColumnCount(3)
        self.companies_table.setHorizontalHeaderLabels(["ID", "Название компании", "Кол-во моделей"])
        self.companies_table.setSortingEnabled(True)
        
        # Настройка размеров столбцов
        header = self.companies_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        
        layout.addWidget(self.companies_table)
        
        return widget
    
    def create_models_tab(self) -> QWidget:
        """Создание вкладки моделей"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # Панель поиска
        search_panel = QHBoxLayout()
        
        self.search_edit = QLineEdit()
        self.search_edit.setPlaceholderText("🔍 Поиск по названию, компании, RAM...")
        self.search_edit.textChanged.connect(self.search_models)
        search_panel.addWidget(self.search_edit)
        
        layout.addLayout(search_panel)
        
        # Таблица моделей
        self.models_table = QTableWidget()
        self.models_table.setColumnCount(11)
        self.models_table.setHorizontalHeaderLabels([
            "ID", "Компания", "Модель", "RAM", "Батарея", 
            "Экран", "Год", "Регионов с ценами", "Действия", "", ""
        ])
        self.models_table.setSortingEnabled(True)
        
        # Настройка размеров столбцов
        header = self.models_table.horizontalHeader()
        # ID - минимальный размер
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        # Компания и Модель - расширяемые
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
        # Характеристики - по содержимому
        for i in range(3, 8):
            header.setSectionResizeMode(i, QHeaderView.ResizeMode.ResizeToContents)
        # Кнопки действий - фиксированные
        for i in range(8, 11):
            header.setSectionResizeMode(i, QHeaderView.ResizeMode.Fixed)
            header.resizeSection(i, 120)
        
        layout.addWidget(self.models_table)
        
        return widget
    
    def create_analytics_tab(self) -> QWidget:
        """Создание вкладки аналитики"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # Статистика по регионам
        stats_group = QGroupBox("📊 Статистика цен по регионам")
        stats_layout = QVBoxLayout()
        
        self.stats_text = QTextEdit()
        self.stats_text.setReadOnly(True)
        self.stats_text.setFont(QFont("Consolas", 10))
        stats_layout.addWidget(self.stats_text)
        
        refresh_stats_btn = QPushButton("🔄 Обновить статистику")
        refresh_stats_btn.clicked.connect(self.update_statistics)
        stats_layout.addWidget(refresh_stats_btn)
        
        stats_group.setLayout(stats_layout)
        layout.addWidget(stats_group)
        
        return widget
    
    def connect_to_db(self):
        """Подключение к БД"""
        if self.db.connect():
            self.status_bar.showMessage("✅ Подключено к БД")
            self.refresh_data()
        else:
            QMessageBox.critical(self, "Ошибка", "Не удалось подключиться к БД!")
    
    def refresh_data(self):
        """Обновление всех данных"""
        self.load_companies()
        self.load_models()
        self.update_statistics()
        self.status_bar.showMessage("✅ Данные обновлены")
    
    def load_companies(self):
        """Загрузка списка компаний"""
        companies = self.db.get_all_companies()
        self.companies_table.setRowCount(len(companies))
        
        for row, company in enumerate(companies):
            # ID
            id_item = QTableWidgetItem(str(company['company_id']))
            id_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.companies_table.setItem(row, 0, id_item)
            
            # Название
            name_item = QTableWidgetItem(company['company_name'])
            name_item.setTextAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
            self.companies_table.setItem(row, 1, name_item)
            
            # Количество моделей
            count_item = QTableWidgetItem(str(company['models_count']))
            count_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.companies_table.setItem(row, 2, count_item)
    
    def load_models(self, search_text=""):
        """Загрузка списка моделей"""
        if search_text:
            models = self.db.search_models(search_text)
        else:
            models = self.db.get_all_models()
        
        self.models_table.setRowCount(len(models))
        
        for row, model in enumerate(models):
            # ID
            id_item = QTableWidgetItem(str(model['model_id']))
            id_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 0, id_item)
            
            # Компания
            company_item = QTableWidgetItem(model['company_name'])
            company_item.setTextAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
            self.models_table.setItem(row, 1, company_item)
            
            # Модель
            model_item = QTableWidgetItem(model['model_name'])
            model_item.setTextAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
            self.models_table.setItem(row, 2, model_item)
            
            # RAM
            ram_item = QTableWidgetItem(model.get('ram', ''))
            ram_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 3, ram_item)
            
            # Батарея
            battery_item = QTableWidgetItem(model.get('battery_capacity', ''))
            battery_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 4, battery_item)
            
            # Экран
            screen_item = QTableWidgetItem(model.get('screen_size', ''))
            screen_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 5, screen_item)
            
            # Год
            year_item = QTableWidgetItem(str(model.get('launched_year', '')))
            year_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 6, year_item)
            
            # Регионов с ценами
            regions_item = QTableWidgetItem(str(model.get('price_regions', 0)))
            regions_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.models_table.setItem(row, 7, regions_item)
            
            # Кнопки действий
            edit_btn = QPushButton("✏️ Редакт.")
            edit_btn.clicked.connect(lambda checked, mid=model['model_id']: self.edit_model(mid))
            self.models_table.setCellWidget(row, 8, edit_btn)
            
            price_btn = QPushButton("💰 Цены")
            price_btn.clicked.connect(
                lambda checked, mid=model['model_id'], name=model['model_name']: 
                self.manage_prices(mid, name)
            )
            self.models_table.setCellWidget(row, 9, price_btn)
            
            delete_btn = QPushButton("🗑️ Удалить")
            delete_btn.clicked.connect(lambda checked, mid=model['model_id']: self.delete_model(mid))
            self.models_table.setCellWidget(row, 10, delete_btn)
    
    def add_company(self):
        """Добавление новой компании"""
        name, ok = QInputDialog.getText(self, "Новая компания", "Введите название компании:")
        if ok and name:
            try:
                self.db.add_company(name)
                self.refresh_data()
                QMessageBox.information(self, "Успех", f"Компания '{name}' добавлена!")
            except Exception as e:
                QMessageBox.critical(self, "Ошибка", f"Ошибка при добавлении: {str(e)}")
    
    def add_model(self):
        """Добавление новой модели"""
        dialog = ModelDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            try:
                model_data = dialog.get_data()
                self.db.add_model(model_data)
                self.refresh_data()
                QMessageBox.information(self, "Успех", "Модель добавлена!")
            except Exception as e:
                QMessageBox.critical(self, "Ошибка", f"Ошибка при добавлении: {str(e)}")
    
    def edit_model(self, model_id):
        """Редактирование модели"""
        model_data = self.db.get_model_by_id(model_id)
        dialog = ModelDialog(self, model_data)
        
        if dialog.exec() == QDialog.DialogCode.Accepted:
            try:
                updated_data = dialog.get_data()
                self.db.update_model(model_id, updated_data)
                self.refresh_data()
                QMessageBox.information(self, "Успех", "Модель обновлена!")
            except Exception as e:
                QMessageBox.critical(self, "Ошибка", f"Ошибка при обновлении: {str(e)}")
    
    def delete_model(self, model_id):
        """Удаление модели"""
        reply = QMessageBox.question(
            self, "Подтверждение",
            "Вы уверены, что хотите удалить эту модель?",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            try:
                self.db.delete_model(model_id)
                self.refresh_data()
                QMessageBox.information(self, "Успех", "Модель удалена!")
            except Exception as e:
                QMessageBox.critical(self, "Ошибка", f"Ошибка при удалении: {str(e)}")
    
    def manage_prices(self, model_id, model_name):
        """Управление ценами модели"""
        dialog = PriceDialog(self, model_id, model_name)
        dialog.exec()
        self.refresh_data()
    
    def search_models(self, text):
        """Поиск моделей"""
        self.load_models(text)
    
    def update_statistics(self):
        """Обновление статистики"""
        try:
            stats = self.db.get_price_statistics()
            
            stats_text = "📊 СТАТИСТИКА ЦЕН ПО РЕГИОНАМ\n" + "="*60 + "\n\n"
            
            for stat in stats:
                region_name = stat['region_name']
                currency_code, currency_symbol = CURRENCY_MAP.get(region_name, ('USD', '$'))
                
                stats_text += f"🌍 {region_name} ({currency_code}):\n"
                stats_text += f"   • Моделей с ценами: {stat['models_count']}\n"
                stats_text += f"   • Средняя цена: {currency_symbol}{stat['avg_price']:,.2f}\n"
                stats_text += f"   • Минимальная цена: {currency_symbol}{stat['min_price']:,.2f}\n"
                stats_text += f"   • Максимальная цена: {currency_symbol}{stat['max_price']:,.2f}\n\n"
            
            self.stats_text.setText(stats_text)
        except Exception as e:
            self.stats_text.setText(f"Ошибка при загрузке статистики: {str(e)}")
    
    def closeEvent(self, event):
        """Обработка закрытия окна"""
        self.db.disconnect()
        event.accept()