<?php

namespace Tanzsport;

class ModuleFormationAdminBackend extends \BackendModule
{

    protected $strTemplate = 'be_form_admin';

    public function __construct()
    {
        parent::__construct();
    }

    public function generate()
    {
        return parent::generate();
    }

    protected function compile()
    {
        if (\Input::post('td_form_admin_import')) {
            $overwrite = \Input::post('overwrite');

            if (isset($GLOBALS["_FILES"]["fdx"])) {
                $up = $GLOBALS["_FILES"]["fdx"];

                $errMsg = null;
                switch ($up["error"]) {
                    case 0:
                        break;
                    case 1:
                    case 2:
                        $errMsg = "Hochgeladene Datei ist zu groß!";
                        break;
                    case 3:
                        $errMsg = "Datei wurde noch teilweise hochgeladen!";
                        break;
                    case 4:
                        $errMsg = "Keine Datei hochgeladen!";
                        break;
                    case 6:
                        $errMsg = "Kein temporäres Verzeichnis für Uploads konfiguriert!";
                        break;
                    case 7:
                        $errMsg = "Hochgeladene Datei konnte nicht gespeichert werden!";
                        break;
                    case 8:
                        $errMsg = "Upload wurde gestoppt!";
                        break;
                }

                if ($errMsg) {
                    \Message::addError($errMsg);
                } else {
                    $this->importieren($up["tmp_name"], $overwrite);
                    unlink($up["tmp_name"]);
                }
            }
            $this->Template->messages_import = \Message::generate();
        }
        if (\Input::post('td_form_admin_copy_saison')) {
            $this->kopieren(\Input::post('src'), \Input::post('target'));
            \Message::addConfirmation('Daten kopiert!');
            $this->Template->messages_copy = \Message::generate();
        }

        $saisonValues = [];
        $saisons = SaisonModel::findAll(['order' => 'jahr DESC']);
        if ($saisons != null) {
            $i = 0;
            foreach ($saisons as $saison) {
                $saisonValues[$saison->id] = [
                    'jahr' => $saison->jahr,
                    'selected_source' => $i === 1,
                    'selected_target' => $i === 0
                ];
                $i++;
            }
        }
        $this->Template->saisons = $saisonValues;
        $this->Template->href = $this->getReferer(true);
        $this->Template->title = specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']);
        $this->Template->button = $GLOBALS['TL_LANG']['MSC']['backBT'];
        $this->Template->action = ampersand(\Environment::get('request'));
        $this->Template->submitButton = specialchars($GLOBALS['TL_LANG']['MSC']['continue']);

        \Message::reset();
    }

    //
    // KOPIEREN
    //
    private function kopieren($source, $target)
    {
        // loeschen der vorhandenen datensätze
        $ligenLoeschen = LigaModel::findBy('pid', $target);
        if ($ligenLoeschen != null) {
            foreach ($ligenLoeschen as $liga) {
                $mannschaftenLoeschen = LigaMannschaftModel::findBy('pid', $liga->id);
                if ($mannschaftenLoeschen != null) {
                    foreach ($mannschaftenLoeschen as $mannschaft) {
                        $mannschaft->delete();
                    }
                }
                $turniereLoeschen = LigaTurnierModel::findBy('pid', $liga->id);
                if ($turniereLoeschen != null) {
                    foreach ($turniereLoeschen as $turnier) {
                        $turnier->delete();
                    }
                }
                $liga->delete();
            }
        }

        // kopieren aus der quelle ins ziel
        $ligenKopieren = LigaModel::findBy('pid', $source);
        if ($ligenKopieren != null) {
            foreach ($ligenKopieren as $liga) {
                /**
                 * @var LigaModel $liga
                 */
                $copyLiga = $liga->createCopyFor($target);
                $copyLiga->save();

                $mannschaftenKopieren = LigaMannschaftModel::findBy('pid', $liga->id);
                if ($mannschaftenKopieren != null) {
                    foreach ($mannschaftenKopieren as $mannschaft) {
                        /**
                         * @var LigaMannschaftModel $mannschaft
                         */
                        $copyMannschaft = $mannschaft->createCopyFor($copyLiga->id);
                        $copyMannschaft->save();
                    }
                }
            }
        }
    }

    //
    // IMPORT
    //
    private function importieren($file, $overwrite = false)
    {
        $raw = file_get_contents($file);

        $daten = unserialize($raw);
        $typ = $daten->typ;
        $saisons = $daten->saisons;

        foreach ($saisons as $saison) {
            $objSaison = $this->importSaison($saison, $overwrite);
            foreach ($saison->ligen as $key => $ligaDaten) {
                $this->importLiga($typ, $objSaison, $ligaDaten, $overwrite);
            }
        }
    }

    private function importSaison(\stdClass $saisonDaten, $overwrite)
    {
        $exists = true;
        $objSaison = SaisonModel::findOneBy('jahr', $saisonDaten->saison);
        if (!$objSaison) {
            $objSaison = new SaisonModel();
            $exists = false;
        }
        if ($overwrite || !$exists) {
            $objSaison->tstamp = time();
            $objSaison->jahr = $saisonDaten->saison;
            $objSaison->published = 1;
            $objSaison->save();
        }

        return $objSaison;
    }

    private function importLiga($typ, SaisonModel $objSaison, \stdClass $ligaDaten, $overwrite = false)
    {
        $objLiga = $this->findOrCreateLiga($typ, $objSaison, $ligaDaten->liga, $overwrite);

        $arrMannschaften = array();
        $arrTurniere = array();

        foreach ($ligaDaten->mannschaften as $i => $mannschaft) {
            $objMannschaft = $this->findOrCreateMannschaft($objLiga, $mannschaft->mannschaft, $overwrite);
            $arrMannschaften[$objMannschaft->id] = $objMannschaft;
        }
        foreach ($ligaDaten->turniere as $i => $turnier) {
            if ($turnier->datum != null) {
                $objTurnier = $this->findOrCreateLigaTurnier($i, $objLiga, $turnier, $ligaDaten->mannschaften, $overwrite);
                $arrTurniere[$objTurnier->id] = $objTurnier;
            }
        }
    }

    private function findOrCreateLiga($typ, SaisonModel $objSaison, \stdClass $liga, $overwrite = false)
    {
        $arrColumns = array('pid = ?');

        // bereich
        $strBereich = $this->translateBereich($typ, $liga->bereich);
        $arrColumns[] = "bereich = '{$strBereich}'";

        // liga
        if (!isset($liga->liga)) {
            throw new \RuntimeException("Daten enthalten keine Ligenbezeichung!");
        }
        $arrColumns[] = "liga = '{$liga->liga}'";

        // turnierart
        if (!isset($liga->turnierart)) {
            throw new \RuntimeException("Daten enthalten keine Turnierart!");
        }
        $arrColumns[] = "turnierart = '{$liga->turnierart}'";

        // nr
        $nr = null;
        $bezeichnung = null;
        if (isset($liga->nr)) {
            if (preg_match('/[^\d]/', $liga->nr)) {
                if ($liga->turnierart == Ergebnisarchiv::TURNIERART_JMD && $liga->liga == Ergebnisarchiv::LIGA_2BL) {
                    if ($liga->nr == 'NOW' || $liga->nr == 'NO') {
                        $nr = 1;
                        if ($liga->nr == 'NOW') {
                            $bezeichnung = 'Nord/Ost/West';
                        } else {
                            $bezeichnung = 'Nord/Ost';
                        }
                    } else {
                        $nr = 2;
                        $bezeichnung = 'Süd/Ost';
                    }
                } else {
                    $nr = $this->translateNummer(strtoupper($liga->nr));
                    $bezeichnung = strtoupper($liga->nr);
                }
            } else {
                $nr = intval($liga->nr);
            }
            $arrColumns[] = "nr = {$nr}";
        }

        $exists = true;
        $objLiga = LigaModel::findOneBy($arrColumns, $objSaison->id);
        if (!$objLiga) {
            $objLiga = new LigaModel();
            $exists = false;
        }

        if ($overwrite || !$exists) {
            $objLiga->tstamp = time();
            $objLiga->pid = $objSaison->id;
            $objLiga->bereich = $strBereich;
            $objLiga->liga = $liga->liga;
            $objLiga->turnierart = $liga->turnierart;
            if ($nr) {
                $objLiga->nr = $nr;
                if ($bezeichnung) {
                    $objLiga->bezeichnung = $bezeichnung;
                }
            }
            $objLiga->published = 1;

            $objLiga->bereichOrder = \Tanzsport\Ergebnisarchiv::getSortIndexBereich($objLiga->bereich);
            $objLiga->ligaOrder = \Tanzsport\Ergebnisarchiv::getSortIndexLiga($objLiga->liga);
            $objLiga->turnierartOrder = \Tanzsport\Ergebnisarchiv::getSortIndexTurnierart($objLiga->turnierart);

            $objLiga->save();
        }

        return $objLiga;
    }

    private function findOrCreateMannschaft(LigaModel $objLiga, \stdClass $m, $overwrite = false)
    {
        $t = LigaMannschaftModel::TABLE;
        $arrColumns = array("$t.pid = ?", "$t.startnr = ?");

        $exists = true;
        $objM = LigaMannschaftModel::findOneBy($arrColumns, array($objLiga->id, $m->startnr));
        if (!$objM) {
            $objM = new LigaMannschaftModel();
            $exists = false;
        }

        if ($overwrite || !$exists) {
            $objM->tstamp = time();
            $objM->liga = $objLiga;
            $objM->startnr = $m->startnr;
            if (isset($m->verein->name)) {
                $objM->verein_name = $m->verein->name;
            }
            if (isset($m->verein->url)) {
                $objM->verein_url = $m->verein->url;
            }
            if (isset($m->team->name)) {
                $objM->team_name = $m->team->name;
            }
            if (isset($m->team->url)) {
                $objM->team_url = $m->team->url;
            }
            if (isset($m->trainer) && count($m->trainer) > 0) {
                $arrTrainer = array();
                foreach ($m->trainer as $t) {
                    $arrTrainer[] = array('name' => $t->name, 'email' => $t->email);
                }
                $objM->trainer = $arrTrainer;
            }
            if (isset($m->kapitaen->name)) {
                $objM->kapitaen_name = $m->kapitaen->name;
            }
            if (isset($m->kapitaen->email)) {
                $objM->kapitaen_email = $m->kapitaen->email;
            }
            if (isset($m->kontakt) && count($m->kontakt) > 0) {
                $arrKontakt = array();
                foreach ($m->kontakt as $k) {
                    $arrKontakt[] = array('name' => $k->name, 'email' => $k->email);
                }
                $objM->kontakt = $arrKontakt;
            }
            if (isset($m->aufstieg)) {
                $objM->aufstieg = $m->aufstieg;
            }
            $objM->bemerkungen = $m->bemerkungen;
            $objM->published = 1;
            $objM->save();
            $m->id = $objM->id;
        } else {
            $m->id = $objM->id;
        }

        return $objM;
    }

    private function findOrCreateLigaTurnier($i, LigaModel $objLiga, \stdClass $turnier, array $mannschaften, $overwrite = false)
    {
        $u = $turnier->datum->format('U');
        $jetzt = new \DateTime('now');
        $istInZukunft = $turnier->datum > $jetzt;

        $table = LigaTurnierModel::TABLE;
        $arrColumns = array("$table.pid = ?", "$table.datum = ?");

        $exists = true;
        $objT = LigaTurnierModel::findOneBy($arrColumns, array($objLiga->id, $u));
        if (!$objT) {
            $objT = new LigaTurnierModel();
            $exists = false;
        }

        if ($overwrite || !$exists) {
            $objT->tstamp = time();
            $objT->datum = $u;
            $objT->ort = $turnier->ort;
            $objT->published = 1;
            $objT->liga = $objLiga;
            if (isset($turnier->turnierstaette)) {
                $objT->tst_halle = $turnier->turnierstaette->halle;
                $objT->tst_adresse = $turnier->turnierstaette->adresse;
            }
            if (isset($turnier->telefonTurniertag)) {
                $objT->tst_telefon = $turnier->telefonTurniertag;
            }
            if (isset($turnier->zeiten)) {
                $objT->zeiten_einlass = $turnier->zeiten->einlass;
                $arrZeiten = array();
                foreach ($turnier->zeiten->beginn as $b) {
                    if ($b->uhrzeit || $b->turnier) {
                        $arrZeiten[] = array('uhrzeit' => $b->uhrzeit, 'text' => $b->turnier);
                    }
                }
                $objT->zeiten_beginn = $arrZeiten;
            }
            if (isset($turnier->karten)) {
                $arrKarten = array();
                foreach ($turnier->karten as $k) {
                    $arrKarten[] = array('preis' => $k->preis, 'text' => $k->text);
                }
                $objT->karten = $arrKarten;
            }
            if (isset($turnier->anfahrt)) {
                if (isset($turnier->anfahrt->url)) {
                    $objT->anfahrt_url = $turnier->anfahrt->url;
                }
                if (isset($turnier->anfahrt->text)) {
                    $objT->anfahrt_text = $turnier->anfahrt->text;
                }
            }
            if (isset($turnier->vorverkauf)) {
                if (isset($turnier->vorverkauf->ausrichter)) {
                    $objT->vvk_text = $turnier->vorverkauf->ausrichter;
                }
                if (isset($turnier->vorverkauf->anschrift)) {
                    $objT->vvk_anschrift = $turnier->vorverkauf->anschrift;
                }
                if (isset($turnier->vorverkauf->telefon)) {
                    $objT->vvk_telefon = $turnier->vorverkauf->telefon;
                }
                if (isset($turnier->vorverkauf->fax)) {
                    $objT->vvk_fax = $turnier->vorverkauf->fax;
                }
                if (isset($turnier->vorverkauf->email)) {
                    $objT->vvk_email_text = $turnier->vorverkauf->email->text;
                    $objT->vvk_email_adresse = $turnier->vorverkauf->email->adresse;
                }
                if (isset($turnier->vorverkauf->onlineticket)) {
                    $objT->vvk_online_url = $turnier->vorverkauf->onlineticket;
                }
            }
            $objT->turnier_published = true;

            if ($turnier->annulliert) {
                $objT->ergebnis_annulliert = 1;
            } else {
                $objT->ergebnis_annulliert = '';
            }

            if ($mannschaften != null && !empty($mannschaften)) {
                $ergebnis = array();
                $anzahlWr = 0;
                $annulliert = false;

                foreach ($mannschaften as $m) {
                    foreach ($m->turniere as $tIndex => $tDaten) {
                        if (!$tDaten->annulliert) {
                            if ($tIndex == $i) {
                                $ergMannschaft = array(
                                    'mannschaft' => $m->mannschaft->id,
                                    'pz' => $tDaten->platz,
                                    'runde' => $ergMannschaft['runde'] = $this->translateRunde($tDaten->runde, $tDaten->status),
                                    'wertung' => $tDaten->wertung,
                                    'disqualifiziert' => $tDaten->disqualifiziert ? 1 : 0,
                                );
                                $ergebnis[] = $ergMannschaft;
                                if (count($ergMannschaft['wertung']) > $anzahlWr) {
                                    $anzahlWr = count($ergMannschaft['wertung']);
                                }
                                break;
                            }
                        } else {
                            if ($tIndex == $i) {
                                $annulliert = true;
                            }
                        }
                    }
                }

                if (!$annulliert) {
                    if (!empty($ergebnis)) {
                        usort($ergebnis, array($this, 'compareErgebnis'));

                        $objT->wertungsrichter_anzahl = $anzahlWr;
                        $objT->ergebnis_annulliert = false;
                        $objT->ergebnis_erfassen = true;
                        $objT->ergebnis = $ergebnis;
                        $objT->ergebnis_published = $istInZukunft ? false : true;
                    }
                } else {
                    if ($annulliert) {
                        $objT->wertungsrichter_anzahl = 0;
                        $objT->ergebnis_annulliert = true;
                        $objT->ergebnis_erfassen = false;
                        $objT->ergebnis = array_fill(0, count($mannschaften), null);
                        $objT->ergebnis_published = true;
                    }
                }
            }

            $objT->save();
        }

        return $objT;
    }

    private function translateBereich($typ, $bereich)
    {
        if ($bereich) {
            return "{$typ}{$bereich}";
        } else {
            return "{$typ}BL";
        }
    }

    private function translateNummer($nummer)
    {
        if ($nummer == 'I') {
            return 1;
        }
        if ($nummer == 'II') {
            return 2;
        }
        if ($nummer == 'III') {
            return 3;
        }
        if ($nummer == 'IV') {
            return 4;
        }
        if ($nummer == 'V') {
            return 5;
        }

        if (strlen($nummer) > 1) {
            throw new \RuntimeException("{$nummer} kann nicht übersetzt werden!");
        }

        return ord($nummer) - ord('A') + 1;
    }

    private function translateRunde($strRunde)
    {
        switch (strtoupper(trim($strRunde))) {
            case 'NA':
                return Ergebnisarchiv::NICHT_ANGETRETEN;
            case 'G':
                return Ergebnisarchiv::RUNDE_GF;
            case 'K':
                return Ergebnisarchiv::RUNDE_KF;
            case 'Z':
                return Ergebnisarchiv::RUNDE_ZR;
            case 'V':
            default:
                return Ergebnisarchiv::RUNDE_VR;
        }
    }

    public function compareErgebnis($a, $b)
    {
        if ($a['pz'] == $b['pz']) {
            return 0;
        } else {
            if ($a['pz'] > $b['pz']) {
                return 1;
            } else {
                return -1;
            }
        }
    }
}
