#include "Colors.h"

#include <QGuiApplication>
#include <QPalette>
#include <QColor>


bool isDarkModeInternal()
{
    QPalette palette = QGuiApplication::palette();
    QColor backgroundColor = palette.color(QPalette::Window);
    return backgroundColor.lightness() < 128; // Check if the background color is dark
}

bool isDarkMode()
{
    static bool darkMode = isDarkModeInternal();
    return darkMode;
}

ColorTheme GetLightMode()
{
    ColorTheme t;

    t.defaultTextColor = Qt::black;

    t.gutterBackground = Qt::lightGray;
    t.lineNumber = Qt::black;
    t.currentLine = QColor(Qt::yellow).lighter(160);
    t.errorLine = QColor(Qt::red).lighter(160);

    t.keyword = QColor(32, 32, 192);
    t.comment = QColor(128, 128, 128);
    t.quotedString = QColor(192, 32, 192);
    t.quotedIdentifier = QColor(192, 128, 32);
    t.type = QColor(32, 192, 32);
    t.parameter = QColor(192, 32, 32);

    t.gigaBytes = QColorConstants::Svg::darkorange;
    t.megaBytes = QColorConstants::Svg::darkgoldenrod;
    t.kiloBytes = QColorConstants::Svg::darkgreen;
    t.bytes = QColorConstants::Svg::darkblue;

    t.booleanTrue = Qt::darkGreen;
    t.booleanFalse = Qt::darkRed;

    t.integerColor = Qt::darkBlue;
    t.floatColor = Qt::darkCyan;
    t.numericColor = Qt::darkGreen;
    t.nullColor = Qt::gray;

    t.numericTypeColor = Qt::darkBlue;
    t.dateTimeTypeColor = Qt::darkMagenta;
    t.stringTypeColor = Qt::darkYellow;

    t.explainTime[0] = QColor(255, 192, 192);
    t.explainTime[1] = QColor(255, 224, 192);
    t.explainTime[2] = QColor(255, 255, 192);
    t.explainTime[3] = QColor(255, 255, 224);

    t.explainEstError[0] = QColor(255, 192, 192);
    t.explainEstError[1] = QColor(255, 224, 192);
    t.explainEstError[2] = QColor(255, 255, 192);

    return t;
}

ColorTheme GetDarkMode()
{
    ColorTheme t;

    t.defaultTextColor = Qt::lightGray;

    t.gutterBackground = QColor(Qt::darkGray).darker(400);
    t.lineNumber = Qt::lightGray;
    t.currentLine = QColor(Qt::darkGray).darker(400);;
    t.errorLine = QColor(Qt::red).darker(180);

    t.keyword = QColor(160, 160, 255);
    t.comment = QColor(160, 160, 160);
    t.quotedString = QColor(255, 160, 255);
    t.quotedIdentifier = QColor(255, 192, 128);
    t.type = QColor(160, 255, 160);
    t.parameter = QColor(255, 160, 160);

    t.gigaBytes = QColorConstants::Svg::lightcoral;
    t.megaBytes = QColorConstants::Svg::lightgoldenrodyellow;
    t.kiloBytes = QColorConstants::Svg::lightgreen;
    t.bytes = QColorConstants::Svg::lightblue;

    t.booleanTrue = QColorConstants::Svg::lightgreen;
    t.booleanFalse = QColorConstants::Svg::lightcoral;

    t.integerColor = QColorConstants::Svg::deepskyblue;
    t.floatColor = QColorConstants::Svg::cyan;
    t.numericColor = QColorConstants::Svg::lime;
    t.nullColor = Qt::darkGray;

    t.numericTypeColor = QColorConstants::Svg::lightblue;
    t.dateTimeTypeColor = QColor(Qt::magenta);
    t.stringTypeColor = QColor(Qt::yellow);

    t.explainTime[0] = QColor(120, 20, 20);
    t.explainTime[1] = QColor(110, 40, 20);
    t.explainTime[2] = QColor(90, 50, 20);
    t.explainTime[3] = QColor(70, 70, 20);

    t.explainEstError[0] = QColor(120, 20, 20);
    t.explainEstError[1] = QColor(90, 50, 20);
    t.explainEstError[2] = QColor(70, 70, 20);

    return t;
}

const ColorTheme& GetColorTheme()
{
    static ColorTheme lightMode = GetLightMode();
    static ColorTheme darkMode = GetDarkMode();

    return isDarkMode() ? darkMode : lightMode;
}

void InitApplicationPalette()
{
    if (isDarkMode())
    {
        QPalette pal = QGuiApplication::palette();
        pal.setColor(QPalette::Active, QPalette::Base, QColor(20, 20, 20));
        pal.setColor(QPalette::Active, QPalette::AlternateBase, Qt::black);
        pal.setColor(QPalette::Inactive, QPalette::Base, QColor(20, 20, 20));
        pal.setColor(QPalette::Inactive, QPalette::AlternateBase, Qt::black);
        QGuiApplication::setPalette(pal);
    }
}

QColor ColorTheme::GetColorForType(Oid oid) const
{
    using namespace Pgsql;

    QColor c;
    switch (oid) {
    case int2_oid:
    case int4_oid:
    case int8_oid:
        c = integerColor;
        break;

    case float4_oid:
    case float8_oid:
        c = floatColor;
        break;

    case numeric_oid:
        c = numericColor;
        break;

    case varchar_oid:
    case text_oid:
    case oid_oid:
    case bool_oid:
    default:
        c = defaultTextColor;
    }
    return c;
}
