#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "DialogNuevoTorneo.h"
#include "DialogAgregarJugador.h"
#include "WidgetBracket.h"
#include "TorneoFactory.h"

#include <QMessageBox>
#include <QFileDialog>
#include <QTextStream>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QTableWidgetItem>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setMinimumSize(1100, 720);

    // Insertar WidgetBracket en el scrollArea del .ui
    m_wBracket = new WidgetBracket;
    ui->scrollBracket->setWidget(m_wBracket);
    ui->scrollBracket->setWidgetResizable(true);

    setupConnections();
    aplicarEstilo();
    actualizarUI();
}

MainWindow::~MainWindow() { delete ui; }

void MainWindow::setupConnections() {
    // Botones de la barra de acción
    connect(ui->btnAgregar, &QPushButton::clicked, this, &MainWindow::onAgregarJugador);
    connect(ui->btnIniciar, &QPushButton::clicked, this, &MainWindow::onIniciarTorneo);
    connect(ui->btnAvanzar, &QPushButton::clicked, this, &MainWindow::onAvanzarRonda);

    // Menú
    connect(ui->actionNuevoTorneo,    &QAction::triggered, this, &MainWindow::onNuevoTorneo);
    connect(ui->actionAgregarJugador, &QAction::triggered, this, &MainWindow::onAgregarJugador);
    connect(ui->actionExportar,       &QAction::triggered, this, &MainWindow::onExportarResultados);
    connect(ui->actionSalir,          &QAction::triggered, this, &QMainWindow::close);
    connect(ui->actionAcercaDe,       &QAction::triggered, this, [this]{
        QMessageBox::about(this, "Gestor de Torneos",
            "<b>Gestor de Torneos de Juegos de Mesa</b><br>Versión 1.0<br><br>"
            "C++17 + Qt Widgets");
    });

    // Click en partida del bracket
    connect(m_wBracket, &WidgetBracket::partidaSeleccionada,
            this, [this](int rondaIdx, int partidaIdx) {
        if (!m_torneo) return;
        auto rondas = m_torneo->getRondas();
        if (rondaIdx >= (int)rondas.size()) return;
        auto& partidas = rondas[rondaIdx]->getPartidas();
        if (partidaIdx >= (int)partidas.size()) return;
        auto& partida = partidas[partidaIdx];
        if (partida->getEstado() == Partida::Estado::FINALIZADA || partida->isBye()) return;

        auto j1 = partida->getJugador1();
        auto j2 = partida->getJugador2();
        QMessageBox box(this);
        box.setWindowTitle("Registrar Resultado");
        box.setText(QString("¿Quién ganó?\n\n%1  vs  %2").arg(j1->getAlias(), j2->getAlias()));
        auto* b1 = box.addButton(j1->getAlias(), QMessageBox::YesRole);
        auto* b2 = box.addButton(j2->getAlias(), QMessageBox::NoRole);
        box.addButton("Cancelar", QMessageBox::RejectRole);
        box.exec();
        if (box.clickedButton() == b1) partida->registrarResultado(j1);
        else if (box.clickedButton() == b2) partida->registrarResultado(j2);
        actualizarUI();
    });
}

void MainWindow::onNuevoTorneo() {
    DialogNuevoTorneo dlg(this);
    if (dlg.exec() != QDialog::Accepted) return;
    if (dlg.getNombre().isEmpty() || dlg.getJuego().isEmpty()) {
        QMessageBox::warning(this, "Error", "El nombre y el juego son obligatorios.");
        return;
    }
    m_torneo = TorneoFactory::crear(dlg.getTipo(), dlg.getNombre(), dlg.getJuego());
    setWindowTitle(QString("🎲 %1 — Gestor de Torneos").arg(dlg.getNombre()));
    actualizarUI();
    statusBar()->showMessage(QString("Torneo '%1' creado.").arg(dlg.getNombre()));
}

void MainWindow::onAgregarJugador() {
    if (!m_torneo) { QMessageBox::information(this, "Atención", "Primero crea un torneo."); return; }
    if (m_torneo->getEstado() != Torneo::Estado::CONFIGURACION) {
        QMessageBox::information(this, "Atención", "No se pueden agregar jugadores una vez iniciado.");
        return;
    }
    DialogAgregarJugador dlg(this);
    if (dlg.exec() != QDialog::Accepted) return;
    if (dlg.getNombre().isEmpty()) { QMessageBox::warning(this, "Error", "El nombre es obligatorio."); return; }
    auto j = std::make_shared<Jugador>(dlg.getNombre(), dlg.getAlias());
    m_torneo->addJugador(j);
    actualizarUI();
    statusBar()->showMessage(QString("Jugador '%1' agregado.").arg(j->getAlias()));
}

void MainWindow::onIniciarTorneo() {
    if (!m_torneo) return;
    if (m_torneo->getJugadores().size() < 2) {
        QMessageBox::warning(this, "Error", "Se necesitan al menos 2 jugadores."); return;
    }
    auto r = QMessageBox::question(this, "Iniciar Torneo",
        QString("¿Iniciar con %1 jugadores? Los emparejamientos serán aleatorios.")
        .arg(m_torneo->getJugadores().size()));
    if (r != QMessageBox::Yes) return;
    m_torneo->iniciarTorneo();
    actualizarUI();
    statusBar()->showMessage("¡Torneo iniciado! Haz clic en una partida para registrar el resultado.");
}

void MainWindow::onAvanzarRonda() {
    if (!m_torneo) return;
    auto ronda = m_torneo->getRondaActual();
    if (!ronda || !ronda->isCompleta()) {
        QMessageBox::information(this, "Atención", "Completa todos los resultados de la ronda actual.");
        return;
    }
    m_torneo->avanzarRonda();
    actualizarUI();
    if (m_torneo->isFinalizado() && m_torneo->getCampeon())
        QMessageBox::information(this, "🏆 ¡Campeón!",
            QString("¡Torneo finalizado!\n\n🏆 Campeón: %1").arg(m_torneo->getCampeon()->getAlias()));
}

void MainWindow::onExportarResultados() {
    if (!m_torneo) return;

    // Cambiamos la extensión y el filtro a .csv
    QString ruta = QFileDialog::getSaveFileName(this, "Exportar a Excel",
                                                m_torneo->getNombre() + "_resultados.csv", "Archivos CSV (*.csv)");

    if (ruta.isEmpty()) return;

    QFile file(ruta);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(this, "Error", "No se pudo abrir el archivo para escritura.");
        return;
    }

    QTextStream out(&file);

    // Metadato para forzar a Excel a interpretar el punto y coma como separador de columnas
    out << "sep=;\n";

    // ─── SECCIÓN 1: METADATOS DEL TORNEO ───
    out << "PROPIEDAD;VALOR\n";
    out << "Torneo;" << m_torneo->getNombre() << "\n";
    out << "Juego;" << m_torneo->getJuego() << "\n";
    out << "Tipo de Torneo;" << m_torneo->tipo() << "\n";
    if (m_torneo->getCampeon()) {
        auto campeon = m_torneo->getCampeon();
        // Se exportan ambos campos en la celda de valor
        out << "Campeon;" << campeon->getNombre() << " (" << campeon->getAlias() << ")\n";
    } else {
        out << "Estado;En desarrollo\n";
    }
    out << "\n"; // Línea en blanco para separar bloques

    // ─── SECCIÓN 2: TABLA DE JUGADORES ───
    out << "TABLA DE POSICIONES Y ESTADO\n";
    out << "Posición;Nombre;Alias;Victorias;Derrotas;Estado Actual\n";

    const auto& jugadores = m_torneo->getJugadores();
    for (int i = 0; i < (int)jugadores.size(); ++i) {
        const auto& j = jugadores[i];
        QString estado;
        if (m_torneo->getCampeon() == j)      estado = "Campeon";
        else if (j->isEliminado())             estado = "Eliminado";
        else if (m_torneo->getEstado() == Torneo::Estado::EN_CURSO) estado = "En competicion";
        else                                   estado = "Inscrito";

        out << (i + 1) << ";"
            << j->getNombre() << ";"
            << j->getAlias() << ";"
            << j->getVictorias() << ";"
            << j->getDerrotas() << ";"
            << estado << "\n";
    }
    out << "\n";

    // ─── SECCIÓN 3: HISTORIAL DE ENFRENTAMIENTOS ───
    out << "HISTORIAL DE PARTIDAS POR RONDA\n";
    out << "Ronda;Jugador 1;Jugador 2;Estado de Partida;Ganador\n";

    for (const auto& ronda : m_torneo->getRondas()) {
        for (const auto& p : ronda->getPartidas()) {
            QString j1 = p->getJugador1() ? p->getJugador1()->getAlias() : "TBD";
            QString j2 = p->getJugador2() ? p->getJugador2()->getAlias() : "TBD";
            QString estadoStr;
            QString ganadorStr = p->getGanador() ? p->getGanador()->getAlias() : "-";

            if (p->isBye()) {
                estadoStr = "BYE (Pase automatico)";
                j2 = "-";
                ganadorStr = j1;
            } else {
                switch (p->getEstado()) {
                case Partida::Estado::PENDIENTE:  estadoStr = "Pendiente"; break;
                case Partida::Estado::EN_CURSO:   estadoStr = "En curso"; break;
                case Partida::Estado::FINALIZADA: estadoStr = "Finalizada"; break;
                default:                          estadoStr = "Desconocido"; break;
                }
            }

            out << ronda->getNombre() << ";"
                << j1 << ";"
                << j2 << ";"
                << estadoStr << ";"
                << ganadorStr << "\n";
        }
    }

    statusBar()->showMessage("Resultados exportados exitosamente a " + ruta);
}

void MainWindow::actualizarUI() {
    bool tieneTorneo = (m_torneo != nullptr);
    bool enCurso    = tieneTorneo && m_torneo->getEstado() == Torneo::Estado::EN_CURSO;
    bool config     = tieneTorneo && m_torneo->getEstado() == Torneo::Estado::CONFIGURACION;
    bool finalizado = tieneTorneo && m_torneo->getEstado() == Torneo::Estado::FINALIZADO;

    ui->btnAgregar->setEnabled(config);
    ui->btnIniciar->setEnabled(config && tieneTorneo && m_torneo->getJugadores().size() >= 2);
    ui->btnAvanzar->setEnabled(enCurso);

    if (!tieneTorneo)
        ui->lblEstado->setText("Sin torneo activo");
    else if (config)
        ui->lblEstado->setText(QString("  %1  |  %2 jugadores  |  Configuracion")
            .arg(m_torneo->getNombre()).arg(m_torneo->getJugadores().size()));
    else if (enCurso) {
        auto ronda = m_torneo->getRondaActual();
        ui->lblEstado->setText(QString("  %1  |  %2  |  Ronda %3/%4")
            .arg(m_torneo->getNombre())
            .arg(ronda ? ronda->getNombre() : "")
            .arg(m_torneo->getRondaActualIdx() + 1)
            .arg(m_torneo->totalRondasEsperadas()));
    } else if (finalizado)
        ui->lblEstado->setText(QString("  %1  |  Campeon: %2")
            .arg(m_torneo->getNombre())
            .arg(m_torneo->getCampeon() ? m_torneo->getCampeon()->getAlias() : "N/A"));

    // ── Tab Jugadores ──────────────────────────
    if (tieneTorneo) {
        const auto& jugadores = m_torneo->getJugadores();
        ui->lblTotal->setText(QString("Total: %1 jugadores inscritos").arg(jugadores.size()));
        ui->tablaJugadores->setRowCount((int)jugadores.size());
        ui->tablaJugadores->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
        ui->tablaJugadores->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
        for (int i = 0; i < (int)jugadores.size(); ++i) {
            const auto& j = jugadores[i];
            ui->tablaJugadores->setItem(i, 0, new QTableWidgetItem(QString::number(i+1)));
            ui->tablaJugadores->setItem(i, 1, new QTableWidgetItem(j->getNombre()));
            ui->tablaJugadores->setItem(i, 2, new QTableWidgetItem(j->getAlias()));
            ui->tablaJugadores->setItem(i, 3, new QTableWidgetItem(
                QString("%1V / %2D").arg(j->getVictorias()).arg(j->getDerrotas())));
            QString estado; QColor color;
            if (m_torneo->getCampeon() == j)      { estado = " Campeon";        color = {255,215,0}; }
            else if (j->isEliminado())             { estado = " Eliminado";       color = {150,70,70}; }
            else if (enCurso)                      { estado = " En competicion";  color = {80,200,130}; }
            else                                   { estado = " Inscrito";        color = {120,160,200}; }
            auto* it = new QTableWidgetItem(estado);
            it->setForeground(color);
            ui->tablaJugadores->setItem(i, 4, it);
            ui->tablaJugadores->setRowHeight(i, 32);
        }
    } else {
        ui->lblTotal->setText("Sin torneo activo");
        ui->tablaJugadores->setRowCount(0);
    }

    // ── Tab Resultados ─────────────────────────
    if (m_torneo && m_torneo->getCampeon()) {
        ui->lblCampeon->setText(QString("  Campeon: %1  ").arg(m_torneo->getCampeon()->getAlias()));
        ui->lblCampeon->setVisible(true);
    } else {
        ui->lblCampeon->setVisible(false);
    }

    QString html;
    html += "<style>h3{color:#e94560;margin:10px 0 4px 0;}"
            ".win{color:#4ade80}.lose{color:#888}.bye{color:#6080a0;font-style:italic}"
            ".pend{color:#6090b0}</style>";
    if (tieneTorneo) {
        for (const auto& ronda : m_torneo->getRondas()) {
            html += QString("<h3>%1</h3>").arg(ronda->getNombre());
            for (const auto& p : ronda->getPartidas()) {
                if (p->isBye()) {
                    html += QString("<div class='bye'>⟳ BYE → %1</div>")
                            .arg(p->getJugador1() ? p->getJugador1()->getAlias() : "?");
                } else if (p->getEstado() == Partida::Estado::FINALIZADA) {
                    auto g=p->getGanador(), j1=p->getJugador1(), j2=p->getJugador2();
                    html += QString("<div><span class='win'>▲ %1</span> vs "
                                    "<span class='lose'>▼ %2</span> → <b class='win'>%3</b></div>")
                            .arg(j1?j1->getAlias():"?").arg(j2?j2->getAlias():"?").arg(g?g->getAlias():"?");
                } else {
                    auto j1=p->getJugador1(), j2=p->getJugador2();
                    html += QString("<div class='pend'>◌ %1 vs %2 [pendiente]</div>")
                            .arg(j1?j1->getAlias():"?").arg(j2?j2->getAlias():"?");
                }
            }
        }
    } else {
        html += "<p style='color:#5070a0'>Crea un torneo para ver los resultados aqui.</p>";
    }
    ui->logResultados->setHtml(html);

    // ── Bracket ───────────────────────────────
    m_wBracket->setTorneo(m_torneo.get());
    m_wBracket->refresh();
}

void MainWindow::aplicarEstilo() {
    setStyleSheet(R"(
        QMainWindow { background:#1a1a2e; }
        QMenuBar { background:#16213e; color:#e0e0e0; padding:4px; }
        QMenuBar::item:selected { background:#0f3460; border-radius:4px; }
        QMenu { background:#16213e; color:#e0e0e0; border:1px solid #0f3460; }
        QMenu::item:selected { background:#0f3460; }
        QToolBar { background:#16213e; border-bottom:1px solid #0f3460; spacing:6px; padding:4px 8px; }
        QToolBar QToolButton { color:#a0b4d0; background:transparent; border:1px solid transparent;
            border-radius:6px; padding:4px 10px; font-size:13px; }
        QToolBar QToolButton:hover { background:#0f3460; color:#fff; border-color:#e94560; }
        QFrame#barraAccion { background:#16213e; border-bottom:2px solid #e94560; }
        QLabel#lblEstado { color:#a0c4d8; font-size:13px; font-weight:bold; }
        QPushButton#btnIniciar { background:#e94560; color:white; border:none; border-radius:8px;
            padding:8px 20px; font-size:13px; font-weight:bold; }
        QPushButton#btnIniciar:hover { background:#ff6b6b; }
        QPushButton#btnIniciar:disabled { background:#4a4a6a; color:#777; }
        QPushButton#btnAgregar { background:#0f3460; color:#a0d4f5; border:1px solid #1a5276;
            border-radius:8px; padding:8px 18px; font-size:13px; }
        QPushButton#btnAgregar:hover { background:#1a5276; color:white; }
        QPushButton#btnAgregar:disabled { background:#252545; color:#555; }
        QPushButton#btnAvanzar { background:#1a7a4a; color:#90f0c0; border:1px solid #27ae60;
            border-radius:8px; padding:8px 18px; font-size:13px; font-weight:bold; }
        QPushButton#btnAvanzar:hover { background:#27ae60; color:white; }
        QPushButton#btnAvanzar:disabled { background:#252535; color:#555; }
        QTabWidget#mainTabs::pane { background:#1a1a2e; border:none; }
        QTabWidget#mainTabs > QTabBar::tab { background:#16213e; color:#7090a0;
            padding:10px 22px; font-size:13px; border:none; border-bottom:3px solid transparent; }
        QTabWidget#mainTabs > QTabBar::tab:selected { color:#e0e0ff; border-bottom:3px solid #e94560;
            background:#1e2a4a; }
        QScrollArea#scrollBracket { background:#1a1a2e; border:none; }
        QTableWidget { background:#16213e; alternate-background-color:#1e2a4a; color:#c8dce8;
            gridline-color:#2a3a5a; border:1px solid #2a3a5a; border-radius:6px; font-size:13px; }
        QHeaderView::section { background:#0f1e3a; color:#80a0c0; padding:8px; border:none;
            border-bottom:2px solid #e94560; font-weight:bold; }
        QTextEdit#logResultados { background:#0f1e35; color:#b0c8e0; border:1px solid #2a3a5a;
            border-radius:8px; font-family:'Courier New',monospace; font-size:13px; padding:10px; }
        QLabel#lblCampeon { background:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 #7a3f00,stop:1 #b8860b);
            color:#ffe066; font-size:20px; font-weight:bold; border-radius:10px; padding:14px; }
        QStatusBar { background:#16213e; color:#607080; font-size:12px; }
    )");
}
