#include "designatormappingmodel.h"
#include "../controller/databasecontroller.h"
#include <QSettings>
#include <QDebug>
#include <QRegularExpression>

// Статические константы для значений по умолчанию
const QList<DesignatorMappingItem> DesignatorMappingModel::DEFAULT_MAPPINGS = {
    // Однобуквенные обозначения
    DesignatorMappingItem("A", "Устройство (общее обозначение)", "Устройства (общее обозначение)", false),
    DesignatorMappingItem("B", "Преобразователь неэлектрических величин в электрические", "Преобразователи неэлектрических величин в электрические", false),
    DesignatorMappingItem("C", "Конденсатор", "Конденсаторы", false),
    DesignatorMappingItem("D", "Схема интегральная, микросборка", "Схемы интегральные, микросборки", false),
    DesignatorMappingItem("E", "Элемент разный", "Элементы разные", false),
    DesignatorMappingItem("F", "Разрядник, предохранитель, устройство защитное", "Разрядники, предохранители, устройства защитные", false),
    DesignatorMappingItem("G", "Генератор, источник питания", "Генераторы, источники питания", false),
    DesignatorMappingItem("H", "Устройство индикационное и сигнальное", "Устройства индикационные и сигнальные", false),
    DesignatorMappingItem("J", "Джампер", "Джамперы", false),
    DesignatorMappingItem("K", "Реле, контактор, пускатель", "Реле, контакторы, пускатели", false),
    DesignatorMappingItem("L", "Катушка индуктивности, дроссель", "Катушки индуктивности, дроссели", false),
    DesignatorMappingItem("M", "Двигатель", "Двигатели", false),
    DesignatorMappingItem("N", "Устройство индикационное и сигнальное", "Устройства индикационные и сигнальные", false),
    DesignatorMappingItem("O", "Оптрон", "Оптроны", false),
    DesignatorMappingItem("P", "Прибор, измерительное оборудование", "Приборы, измерительное оборудование", false),
    DesignatorMappingItem("Q", "Выключатель и разъединитель в силовых цепях", "Выключатели и разъединители в силовых цепях", false),
    DesignatorMappingItem("R", "Резистор", "Резисторы", false),
    DesignatorMappingItem("S", "Устройство коммутационное в цепях управления", "Устройства коммутационные в цепях управления", false),
    DesignatorMappingItem("T", "Трансформатор, автотрансформатор", "Трансформаторы, автотрансформаторы", false),
    DesignatorMappingItem("U", "Устройство связи", "Устройства связи", false),
    DesignatorMappingItem("V", "Прибор электровакуумный и полупроводниковый", "Приборы электровакуумные и полупроводниковые", false),
    DesignatorMappingItem("W", "Линия и элемент СВЧ", "Линии и элементы СВЧ", false),
    DesignatorMappingItem("X", "Соединение контактное", "Соединения контактные", false),
    DesignatorMappingItem("Y", "Устройство механическое с электромагнитным приводом", "Устройства механические с электромагнитным приводом", false),
    DesignatorMappingItem("Z", "Устройство оконечное фильтр Ограничитель", "Устройства оконечные фильтры Ограничители", false),
    
    // Двухбуквенные обозначения - группа B
    DesignatorMappingItem("BA", "Громкоговоритель", "Громкоговорители", false),
    DesignatorMappingItem("BB", "Магнитострикционный элемент", "Магнитострикционные элементы", false),
    DesignatorMappingItem("BD", "Детектор ионизирующих излучений", "Детекторы ионизирующих излучений", false),
    DesignatorMappingItem("BE", "Сельсин-приемник", "Сельсины-приемники", false),
    DesignatorMappingItem("BF", "Телефон (капсюль)", "Телефоны (капсюли)", false),
    DesignatorMappingItem("BC", "Сельсин-датчик", "Сельсины-датчики", false),
    DesignatorMappingItem("BK", "Тепловой датчик", "Тепловые датчики", false),
    DesignatorMappingItem("BL", "Фотоэлемент", "Фотоэлементы", false),
    DesignatorMappingItem("BM", "Микрофон", "Микрофоны", false),
    DesignatorMappingItem("BP", "Датчик давления", "Датчики давления", false),
    DesignatorMappingItem("BQ", "Пьезоэлемент", "Пьезоэлементы", false),
    DesignatorMappingItem("BR", "Датчик частоты вращения (тахогенератор)", "Датчики частоты вращения (тахогенераторы)", false),
    DesignatorMappingItem("BS", "Звукосниматель", "Звукосниматели", false),
    DesignatorMappingItem("BV", "Датчик скорости", "Датчики скорости", false),
    
    // Двухбуквенные обозначения - группа D
    DesignatorMappingItem("DA", "Схема интегральная аналоговая", "Схемы интегральные аналоговые", false),
    DesignatorMappingItem("DD", "Схема интегральная, цифровая, логический элемент", "Схемы интегральные, цифровые, логические элементы", false),
    DesignatorMappingItem("DS", "Устройство хранения информации", "Устройства хранения информации", false),
    DesignatorMappingItem("DT", "Устройство задержки", "Устройства задержки", false),
    
    // Двухбуквенные обозначения - группа E
    DesignatorMappingItem("EK", "Нагревательный элемент", "Нагревательные элементы", false),
    DesignatorMappingItem("EL", "Лампа осветительная", "Лампы осветительные", false),
    DesignatorMappingItem("ET", "Пиропатрон", "Пиропатроны", false),
    
    // Двухбуквенные обозначения - группа F
    DesignatorMappingItem("FA", "Дискретный элемент защиты по току мгновенного действия", "Дискретные элементы защиты по току мгновенного действия", false),
    DesignatorMappingItem("FP", "Дискретный элемент защиты по току инерционного действия", "Дискретные элементы защиты по току инерционного действия", false),
    DesignatorMappingItem("FU", "Предохранитель плавкий", "Предохранители плавкие", false),
    DesignatorMappingItem("FV", "Дискретный элемент защиты по напряжению, разрядник", "Дискретные элементы защиты по напряжению, разрядники", false),
    
    // Двухбуквенные обозначения - группа G
    DesignatorMappingItem("GB", "Батарея", "Батареи", false),
    
    // Двухбуквенные обозначения - группа H
    DesignatorMappingItem("HA", "Прибор звуковой сигнализации", "Приборы звуковой сигнализации", false),
    DesignatorMappingItem("HG", "Индикатор символьный", "Индикаторы символьные", false),
    DesignatorMappingItem("HL", "Прибор световой сигнализации", "Приборы световой сигнализации", false),
    
    // Двухбуквенные обозначения - группа K
    DesignatorMappingItem("KA", "Реле токовое", "Реле токовые", false),
    DesignatorMappingItem("KH", "Реле указательное", "Реле указательные", false),
    DesignatorMappingItem("KK", "Реле элекгротепловое", "Реле элекгротепловые", false),
    DesignatorMappingItem("KM", "Контактор, магнитный пускатель", "Контакторы, магнитные пускатели", false),
    DesignatorMappingItem("KT", "Реле времени", "Реле времени", false),
    DesignatorMappingItem("KV", "Реле напряжения", "Реле напряжения", false),
    
    // Двухбуквенные обозначения - группа L
    DesignatorMappingItem("LL", "Дроссель люминесцентного освещения", "Дроссели люминесцентного освещения", false),
    
    // Двухбуквенные обозначения - группа P
    DesignatorMappingItem("PA", "Амперметр", "Амперметры", false),
    DesignatorMappingItem("PC", "Счетчик импульсов", "Счетчики импульсов", false),
    DesignatorMappingItem("PF", "Частотомер", "Частотомеры", false),
    DesignatorMappingItem("PI", "Счетчик активной энергии", "Счетчики активной энергии", false),
    DesignatorMappingItem("PK", "Счетчик реактивной энергии", "Счетчики реактивной энергии", false),
    DesignatorMappingItem("PR", "Омметр", "Омметры", false),
    DesignatorMappingItem("PS", "Регистрирующий прибор", "Регистрирующие приборы", false),
    DesignatorMappingItem("PT", "Часы, измеритель времени действия", "Часы, измерители времени действия", false),
    DesignatorMappingItem("PV", "Вольтметр", "Вольтметры", false),
    DesignatorMappingItem("PW", "Ваттметр", "Ваттметры", false),
    
    // Двухбуквенные обозначения - группа Q
    DesignatorMappingItem("QF", "Выключатель автоматический", "Выключатели автоматические", false),
    DesignatorMappingItem("QK", "Короткозамыкатель", "Короткозамыкатели", false),
    DesignatorMappingItem("QS", "Разъединитель", "Разъединители", false),
    
    // Двухбуквенные обозначения - группа R
    DesignatorMappingItem("RK", "Терморезистор", "Терморезисторы", false),
    DesignatorMappingItem("RP", "Потенциометр", "Потенциометры", false),
    DesignatorMappingItem("RS", "Шунт измерительный", "Шунты измерительные", false),
    DesignatorMappingItem("RU", "Варистор", "Варисторы", false),
    
    // Двухбуквенные обозначения - группа S
    DesignatorMappingItem("SA", "Выключатель или переключатель", "Выключатели или переключатели", false),
    DesignatorMappingItem("SB", "Выключатель кнопочный", "Выключатели кнопочные", false),
    DesignatorMappingItem("SF", "Выключатель автоматический", "Выключатели автоматические", false),
    DesignatorMappingItem("SL", "Выключатель, срабатывающий от уровня", "Выключатели, срабатывающие от уровня", false),
    DesignatorMappingItem("SP", "Выключатель, срабатывающий от давления", "Выключатели, срабатывающие от давления", false),
    DesignatorMappingItem("SQ", "Выключатель, срабатывающий от положения (путевой)", "Выключатели, срабатывающие от положения (путевые)", false),
    DesignatorMappingItem("SR", "Выключатель, срабатывающий от частоты вращения", "Выключатели, срабатывающие от частоты вращения", false),
    DesignatorMappingItem("SK", "Выключатель, срабатывающий от температуры", "Выключатели, срабатывающие от температуры", false),
    
    // Двухбуквенные обозначения - группа T
    DesignatorMappingItem("TA", "Трансформатор тока", "Трансформаторы тока", false),
    DesignatorMappingItem("TS", "Электромагнитный стабилизатор", "Электромагнитные стабилизаторы", false),
    DesignatorMappingItem("TV", "Трансформатор напряжения", "Трансформаторы напряжения", false),
    
    // Двухбуквенные обозначения - группа U
    DesignatorMappingItem("UB", "Модулятор", "Модуляторы", false),
    DesignatorMappingItem("UR", "Демодулятор", "Демодуляторы", false),
    DesignatorMappingItem("UI", "Дискриминатор", "Дискриминаторы", false),
    DesignatorMappingItem("UZ", "Преобразователь частотный, инвертор, генератор частоты, выпрямитель", "Преобразователи частотные, инверторы, генераторы частоты, выпрямители", false),
    
    // Двухбуквенные обозначения - группа V
    DesignatorMappingItem("VD", "Диод, стабилитрон", "Диоды, стабилитроны", false),
    DesignatorMappingItem("VL", "Прибор электровакуумный", "Приборы электровакуумные", false),
    DesignatorMappingItem("VT", "Транзистор", "Транзисторы", false),
    DesignatorMappingItem("VS", "Тиристор", "Тиристоры", false),
    
    // Двухбуквенные обозначения - группа W
    DesignatorMappingItem("WE", "Ответвитель", "Ответвители", false),
    DesignatorMappingItem("WK", "Короткозамыкатель", "Короткозамыкатели", false),
    DesignatorMappingItem("WS", "Вентиль", "Вентили", false),
    DesignatorMappingItem("WT", "Трансформатор, неоднородность, фазовращатель", "Трансформаторы, неоднородности, фазовращатели", false),
    DesignatorMappingItem("WU", "Аттенюатор", "Аттенюаторы", false),
    DesignatorMappingItem("WA", "Антенна", "Антенны", false),
    
    // Двухбуквенные обозначения - группа X
    DesignatorMappingItem("XA", "Токосъемник, контакт скользящий Штырь", "Токосъемники, контакты скользящие Штыри", false),
    DesignatorMappingItem("XP", "Гнездо", "Гнезда", false),
    DesignatorMappingItem("XS", "Соединение разборное", "Соединения разборные", false),
    DesignatorMappingItem("XT", "Соединитель высокочастотный", "Соединители высокочастотные", false),
    
    // Двухбуквенные обозначения - группа Y
    DesignatorMappingItem("YA", "Электромагнит", "Электромагниты", false),
    DesignatorMappingItem("YB", "Тормоз с электромагнитным приводом", "Тормоза с электромагнитным приводом", false),
    DesignatorMappingItem("YC", "Муфта с электромагнитным приводом", "Муфты с электромагнитным приводом", false),
    DesignatorMappingItem("YH", "Электромагнитный патрон или плита", "Электромагнитные патроны или плиты", false),
    
    // Двухбуквенные обозначения - группа Z
    DesignatorMappingItem("ZL", "Ограничитель", "Ограничители", false),
    DesignatorMappingItem("ZQ", "Фильтр кварцевый", "Фильтры кварцевые", false)
};

DesignatorMappingModel::DesignatorMappingModel(QObject *parent)
    : QObject(parent)
    , m_isModified(false)
    , m_dbController(nullptr)
{
    initializeDefaultMappings();
    // Не загружаем из БД в конструкторе, так как БД еще не инициализирована
    // loadFromDatabase() будет вызван после инициализации БД
}

QList<DesignatorMappingItem> DesignatorMappingModel::mappings() const
{
    return m_mappings;
}

void DesignatorMappingModel::setMappings(const QList<DesignatorMappingItem> &newMappings)
{
    if (m_mappings != newMappings) {
        m_mappings = newMappings;
        updateMappingMap();
        setModified(true);
        emit mappingsChanged();
    }
}

QString DesignatorMappingModel::getComponentType(const QString &designator, bool isPlural) const
{
    // Извлекаем буквенную часть дезигнатора (первые 1-2 символа)
    QRegularExpression regex("^([A-Z]{1,2})");
    QRegularExpressionMatch match = regex.match(designator.toUpper());
    
    if (match.hasMatch()) {
        QString letterPart = match.captured(1);
        
        // Ищем в карте маппинга
        auto it = m_mappingMap.find(letterPart);
        if (it != m_mappingMap.end()) {
            return isPlural ? it.value().pluralName : it.value().singularName;
        }
    }
    
    // Если не найдено, возвращаем пустую строку
    return QString();
}

void DesignatorMappingModel::addMapping(const DesignatorMappingItem &item)
{
    // Проверяем, не существует ли уже такой дезигнатор
    for (int i = 0; i < m_mappings.size(); ++i) {
        if (m_mappings[i].designator == item.designator) {
            updateMapping(item.designator, item);
            return;
        }
    }
    
    m_mappings.append(item);
    updateMappingMap();
    setModified(true);
    emit mappingAdded(item.designator);
    emit mappingsChanged();
}

void DesignatorMappingModel::updateMapping(const QString &designator, const DesignatorMappingItem &item)
{
    for (int i = 0; i < m_mappings.size(); ++i) {
        if (m_mappings[i].designator == designator) {
            m_mappings[i] = item;
            updateMappingMap();
            setModified(true);
            emit mappingUpdated(designator);
            emit mappingsChanged();
            return;
        }
    }
}

void DesignatorMappingModel::removeMapping(const QString &designator)
{
    for (int i = 0; i < m_mappings.size(); ++i) {
        if (m_mappings[i].designator == designator) {
            m_mappings.removeAt(i);
            updateMappingMap();
            setModified(true);
            emit mappingRemoved(designator);
            emit mappingsChanged();
            return;
        }
    }
}

void DesignatorMappingModel::clearCustomMappings()
{
    m_mappings.erase(
        std::remove_if(m_mappings.begin(), m_mappings.end(),
                      [](const DesignatorMappingItem &item) { return item.isCustom; }),
        m_mappings.end()
    );
    updateMappingMap();
    setModified(true);
    emit mappingsChanged();
}

void DesignatorMappingModel::resetToDefaults()
{
    m_mappings = DEFAULT_MAPPINGS;
    updateMappingMap();
    setModified(true);
    emit mappingsChanged();
}

bool DesignatorMappingModel::isModified() const
{
    return m_isModified;
}

void DesignatorMappingModel::setModified(bool modified)
{
    if (m_isModified != modified) {
        m_isModified = modified;
        if (modified) {
            emit settingsModified();
        }
    }
}

void DesignatorMappingModel::setDatabaseController(DataBaseController *dbController)
{
    m_dbController = dbController;
}

void DesignatorMappingModel::loadDataFromDatabase()
{
    // Загружаем данные из БД после её инициализации
    loadFromDatabase();
}

void DesignatorMappingModel::saveToDatabase()
{
    if (!m_dbController) {
        qDebug() << "DesignatorMappingModel: DataBaseController не установлен";
        return;
    }
    
    qDebug() << "DesignatorMappingModel: Сохраняем" << m_mappings.size() << "маппингов в БД";
    qDebug() << "DesignatorMappingModel: Путь к БД:" << m_dbController->getDatabasePath();
    
    // Конвертируем DesignatorMappingItem в DesignatorMappingData
    QList<DesignatorMappingData> mappings;
    for (const auto &item : m_mappings) {
        DesignatorMappingData data;
        data.id = -1; // ID будет установлен БД
        data.designator = item.designator;
        data.singularName = item.singularName;
        data.pluralName = item.pluralName;
        data.isCustom = item.isCustom;
        mappings.append(data);
    }
    
    if (m_dbController->saveDesignatorMappings(mappings)) {
        setModified(false);
        qDebug() << "DesignatorMappingModel: Маппинги успешно сохранены в БД:" << m_dbController->getDatabasePath();
    } else {
        qDebug() << "DesignatorMappingModel: Ошибка сохранения маппингов в БД:" << m_dbController->lastError();
    }
}

void DesignatorMappingModel::loadFromDatabase()
{
    if (!m_dbController) {
        qDebug() << "DesignatorMappingModel: DataBaseController не установлен, используем значения по умолчанию";
        m_mappings = DEFAULT_MAPPINGS;
        updateMappingMap();
        setModified(false);
        return;
    }
    
    qDebug() << "DesignatorMappingModel: Загружаем маппинги из БД:" << m_dbController->getDatabasePath();
    
    QList<DesignatorMappingData> dbMappings = m_dbController->getAllDesignatorMappings();
    
    if (dbMappings.isEmpty()) {
        // Если в БД нет данных, используем значения по умолчанию
        qDebug() << "DesignatorMappingModel: В БД нет маппингов, используем значения по умолчанию";
        m_mappings = DEFAULT_MAPPINGS;
        updateMappingMap();
        setModified(false);
        return;
    }
    
    // Конвертируем DesignatorMappingData в DesignatorMappingItem
    m_mappings.clear();
    for (const auto &data : dbMappings) {
        DesignatorMappingItem item;
        item.designator = data.designator;
        item.singularName = data.singularName;
        item.pluralName = data.pluralName;
        item.isCustom = data.isCustom;
        m_mappings.append(item);
    }
    
    updateMappingMap();
    setModified(false);
    qDebug() << "DesignatorMappingModel: Загружено" << m_mappings.size() << "маппингов из БД:" << m_dbController->getDatabasePath();
}

void DesignatorMappingModel::updateMappingMap()
{
    m_mappingMap.clear();
    for (const auto &item : m_mappings) {
        m_mappingMap[item.designator] = item;
    }
}

void DesignatorMappingModel::initializeDefaultMappings()
{
    m_mappings = DEFAULT_MAPPINGS;
    updateMappingMap();
} 