/**
 * \file output/odspsm.cpp
 * \date 19/07/2025
 * \author Olivier Langella
 * \brief ODS PSM export
 */


/*
 * SpecGlobTool, Spectra to peptide alignment tool
 * Copyright (C) 2023  Olivier Langella
 * <olivier.langella@universite-paris-saclay.fr>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "odspsm.h"
#include <QCborArray>
#include <pappsomspp/core/peptide/peptideproformaparser.h>
#include <qcontainerfwd.h>
#include <qdebug.h>
#include <qlogging.h>


OdsPsm::OdsPsm(CalcWriterInterface &output) : m_output(output)
{

  qDebug();
}

void
OdsPsm::parameterMapReady(pappso::UiMonitorInterface &monitor [[maybe_unused]])
{

  qDebug();
  m_output.writeSheet("psm list");

  OdsTableSettings table_settings;
  table_settings.setVerticalSplit(1);
  m_output.setCurrentOdsTableSettings(table_settings);

  m_output.writeCell("index");
  m_output.writeCell("sample");
  m_output.writeCell("Proforma");
  m_output.writeCell("precursor charge");
  m_output.writeCell("precursor mz");
  m_output.writeCell("precursor mass");
  m_output.writeCell("peptide mass");
  m_output.writeCell("protein positions");
  //    mpa_calcWriter->writeCell("precursor mass");
  /*
      mpa_calcWriter->writeCell("number of candidates");
      mpa_calcWriter->writeCell("category");

      // colum titles for each peptide candidate
      mpa_calcWriter->writeCell("sequence");
      */

  m_output.writeCell("presence in target database");
  //    mpa_calcWriter->writeCell("presence in target database");
  m_output.writeCell("presence in decoy database");
  //    mpa_calcWriter->writeCell("presence in decoy database");
  m_output.writeCell("spc");
  m_output.setCellAnnotation("peak count");
  m_output.writeCell("spoms score");
  m_output.setCellAnnotation("spoms alignment score");
  m_output.writeCell("interpretation");
  m_output.setCellAnnotation("spoms interpretation");
  //  mpa_calcWriter->writeCell("mass delta positions");
  //    mpa_calcWriter->writeCell("proteins");
  //
  //
  //
  m_output.writeCell("post spc");
  m_output.setCellAnnotation("post treatment peak count");
  m_output.writeCell("post spoms score");
  m_output.setCellAnnotation("post treatment spoms alignment score");
  m_output.writeCell("post interpretation");
  m_output.setCellAnnotation("post treatment spoms interpretation");
  m_output.writeCell("post non aligned mass");
  m_output.setCellAnnotation("post treatment non aligned mass");

  if(m_cborParameterMap.contains(QString("features")))
    {
      m_output.writeCell("Hyperscore");
      m_output.writeCell("TIC (log)");
      m_output.writeCell("MaxIntALL (log)");
      m_output.writeCell("MaxYionInt (log)");
      m_output.writeCell("MaxBionInt (log)");
      m_output.writeCell("SumYmatchInt (log)");
      m_output.writeCell("SumBmatchInt (log)");
      m_output.writeCell("FracYmatchInt");
      m_output.writeCell("FracBmatchInt");
      m_output.writeCell("SeqCoverYion");
      m_output.writeCell("SeqCoverBion");
      m_output.writeCell("ConsecutiveYion");
      m_output.writeCell("ConsecutiveBion");
    }

  m_output.writeLine();
  qDebug();
}

OdsPsm::~OdsPsm()
{
  qDebug();
}

void
OdsPsm::close()
{
  m_output.close();
}


void
OdsPsm::psmReady(pappso::UiMonitorInterface &monitor [[maybe_unused]])
{

  qDebug() << "coucou";
  m_output.writeCell((std::size_t)m_cborScanId.value("index").toInteger());
  m_output.writeCell(m_currentSampleName);
  m_output.writeCell(m_currentPsmProforma);

  int charge    = m_cborScanPrecursor.value("z").toInteger();
  double exp_mz = m_cborScanPrecursor.value("mz").toDouble();
  double exp_mh = getPrecursorMass(exp_mz, charge);
  m_output.writeCell(charge);
  m_output.writeCell(exp_mz);
  m_output.writeCell(exp_mh);


  m_output.writeCell(
    pappso::PeptideProFormaParser::parseString(m_currentPsmProforma)
      ->getMass());


  QStringList accessions;
  for(auto protein_ref : m_currentPsmProteinRefList)
    {
      QStringList positions;
      for(auto position : protein_ref.positions)
        {
          positions << QString::number(position);
        }
      accessions << QString("%1[%2]")
                      .arg(protein_ref.accession)
                      .arg(positions.join(","));
    }
  m_output.writeCell(accessions.join(" "));


  m_output.writeCell(currentProteinRefListContainsTarget());

  m_output.writeCell(currentProteinRefListContainsDecoy());

  qDebug();
  QCborMap cbor_peptidoms = m_cborScanPsmEval.value("peptidoms").toMap();
  if(!cbor_peptidoms.isEmpty())
    {

      // m_output.writeCell("peptidoms count");
      m_output.writeCell((int)cbor_peptidoms.value("spc").toInteger());
      // m_output.writeCell("peptidoms score");
      m_output.writeCell((int)cbor_peptidoms.value("score").toInteger());
      // m_output.writeCell("peptidoms brackets");
      m_output.writeCell(cbor_peptidoms.value("bracket").toString());
      // m_output.writeCell("mass delta");
      m_output.writeCell(cbor_peptidoms.value("nam").toDouble());
    }


  qDebug();
  QCborMap cbor_spoms = m_cborScanPsmEval.value("spoms").toMap();
  if(!cbor_spoms.isEmpty())
    {

      QCborMap cbor_spoms_first = cbor_spoms.value("first").toMap();

      if(!cbor_spoms_first.isEmpty())
        {
          // m_output.writeCell("peptidoms count");
          m_output.writeCell((int)cbor_spoms_first.value("spc").toInteger());
          // m_output.writeCell("peptidoms score");
          m_output.writeCell((int)cbor_spoms_first.value("score").toInteger());
          // m_output.writeCell("peptidoms brackets");
          m_output.writeCell(cbor_spoms_first.value("bracket").toString());
        }
      QCborMap cbor_spoms_post = cbor_spoms.value("post").toMap();

      if(!cbor_spoms_post.isEmpty())
        {
          // m_output.writeCell("peptidoms count");
          m_output.writeCell((int)cbor_spoms_post.value("spc").toInteger());
          // m_output.writeCell("peptidoms score");
          m_output.writeCell((int)cbor_spoms_post.value("score").toInteger());
          // m_output.writeCell("peptidoms brackets");
          m_output.writeCell(cbor_spoms_post.value("bracket").toString());
          // m_output.writeCell("mass delta");
          m_output.writeCell(cbor_spoms_post.value("nam").toDouble());
        }
    }

  qDebug();
  QCborMap cbor_features = m_cborScanPsmEval.value("features").toMap();
  if(!cbor_features.isEmpty())
    {
      m_output.writeCell(cbor_features.value("hyperscore").toDouble());
      m_output.writeCell(cbor_features.value("total_intensity").toDouble());
      // m_output.writeCell("MaxIntALL");
      m_output.writeCell(cbor_features.value("max_intensity").toDouble());
      // m_output.writeCell("MaxYionInt");
      m_output.writeCell(cbor_features.value("MaxYionInt").toDouble());
      // m_output.writeCell("MaxBionInt");
      m_output.writeCell(cbor_features.value("MaxBionInt").toDouble());
      // m_output.writeCell("SumYmatchInt");
      m_output.writeCell(cbor_features.value("SumYmatchInt").toDouble());
      // m_output.writeCell("SumBmatchInt");
      m_output.writeCell(cbor_features.value("SumBmatchInt").toDouble());
      // m_output.writeCell("FracYmatchInt");
      m_output.writeCell(cbor_features.value("FracYmatchInt").toDouble());
      // m_output.writeCell("FracBmatchInt");
      m_output.writeCell(cbor_features.value("FracBmatchInt").toDouble());
      // m_output.writeCell("SeqCoverYion");
      m_output.writeCell(cbor_features.value("SeqCoverYion").toDouble());
      // m_output.writeCell("SeqCoverBion");
      m_output.writeCell(cbor_features.value("SeqCoverBion").toDouble());
      // m_output.writeCell("ConsecutiveYion");
      m_output.writeCell(
        (int)cbor_features.value("ConsecutiveYion").toInteger());
      // m_output.writeCell("ConsecutiveBion");
      m_output.writeCell(
        (int)cbor_features.value("ConsecutiveBion").toInteger());
    }
  m_output.writeLine();
}
