<?php

declare(strict_types=1);

namespace App\Infrastructure\Persistence\Account;

use App\Application\Settings\SettingsInterface;
use App\Domain\Account\Account;
use App\Domain\Account\AccountNotFoundException;
use App\Domain\Account\AccountRepository;
use App\Domain\Account\AccountVerificationResult;
use App\Domain\Auth\PasswordResetTokenExpiredException;
use App\Domain\Auth\PasswordResetTokenNotFoundException;
use App\Infrastructure\Persistence\SqlHelper;
use App\Infrastructure\Service\Geocoder;
use App\Infrastructure\Service\PKPassGenerator;
use App\Infrastructure\Service\TokenIssuer;
use App\Infrastructure\Service\Mailsender;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use PDO;
use Psr\Log\LoggerInterface;

class DatabaseAccountRepository implements AccountRepository
{
    protected LoggerInterface $logger;
    protected Geocoder $geocoder;
    protected PDO $db;
    protected PKPassGenerator $pkpass;
    protected SettingsInterface $settings;
    protected Mailsender $mail;
    
    public function __construct(
        LoggerInterface $logger, 
         Geocoder $geocoder,
         PDO $database,
         PKPassGenerator $pkpass,
         SettingsInterface $settings, 
         Mailsender $mail
     ) {
        $this->logger = $logger;
        $this->geocoder = $geocoder;
        $this->db = $database;
        $this->pkpass = $pkpass;
        $this->settings = $settings;
        $this->mail = $mail;
    }

    public function checkEMail(string $email,string $accountId = '0') : bool {
        
        $this->logger->debug('DatabaseAccountRepository::checkEMail()', ['email' => $email]);
        
        $stmt = $this->db->prepare('SELECT id FROM account WHERE email = ? AND id!=?');
        $stmt->execute([$email,$accountId]);
        
        $row = $stmt->fetch();
        
        if (!$row) {
            return false;
        }
        else {
            return true;    
        }
    } 
        
    private function generateNextCustomerNo() : string {
        $query = "SELECT customerno FROM customer ORDER by customerno DESC LIMIT 1";   
        $stmt = $this->db->prepare($query);
        $stmt->execute();
        $row = $stmt->fetch();
        
        if($row) {
            $cno = intval($row['customerno']);
        }
        else {
            $cno = 100000;
        }
        $cno++;
        return "$cno"; 
    }
    
    public function putUnverifiedAccount(string $email, string $passwordHash, string $verificationToken, array $additionalValues = []): int {
        //$this->logger->debug('DatabaseAccountRepository::putUnverifiedAccount()', $additionalValues);

        $params = []; //$additionalValues;
        //$params['email'] = $email;
        //$params['passwordHash'] = $passwordHash;
        //$params['verificationToken'] = $verificationToken;
        $cno = $this->generateNextCustomerNo();
        
        // erst customer:
        $query = "INSERT INTO customer SET
                    email = ?,
                    name = ?,
                    customerno = ?,
                    isEnabled='0',
                    isVerified='0',                    
                    createdAt=Now()
                    ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $email,
            $additionalValues['firma'],
            $cno
        ]);
        
        $cid = (int)$this->db->lastInsertId();
        
        // erster Account ist der Admin      
        $query = "INSERT INTO account SET
                        name = ?,
                        vorname = ?,
                        email = ?,
                        passwordHash = ?,
                        verificationToken = ?,
                        createdAt=Now(),
                        customerId = ?,
                        type='BACKEND_USER',
                        accountgroupid='0'
                    ";
       
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $additionalValues['name'],
            $additionalValues['vorname'],
            $email,
            $passwordHash,
            $verificationToken,
            $cid
        ]);
        $aid = (int)$this->db->lastInsertId();
        
        // lat/long ermitteln
        $addressline = $additionalValues['strasse'] . ',' . $additionalValues['plz'] . ' ' . $additionalValues['ort'] . ',' . $additionalValues['land'];
        
        $this->logger->debug('g::putUnverifiedAccount()', ['adressse' => $addressline]);
        
        $latlng = $this->geocoder->geocode($addressline);
        
        $this->logger->debug('address',['line' => $addressline,'latlng'=>$latlng]);
        
        if($latlng) {
            $additionalValues['latitude'] = $latlng->lat;
            $additionalValues['longitude'] = $latlng->lng;   
        }
        
        // erste Adresse anlegen für customer / company
        $query = "INSERT INTO address SET
                    contactID = ?,
                    type='COMPANY',
                    telefon1 = ?,
                    street = ?,
                    postcode = ?,
                    city = ?,
                    country = ?,
                    state = ?,
                    latitude = ?,
                    longitude = ?,
                    createdAt=Now()
                ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $cid,
            $additionalValues['phone'],
            $additionalValues['strasse'],
            $additionalValues['plz'],
            $additionalValues['ort'],
            $additionalValues['land'],
            $additionalValues['state'],
            $additionalValues['latitude'],
            $additionalValues['longitude']
        ]);
        $adid = (int)$this->db->lastInsertId();        
                
        // Adresse für Hauptmitarbeiter
        $query = "INSERT INTO address SET
                    contactID = ?,
                    type='USER',
                    telefon1 = ?,
                    street = ?,
                    postcode = ?,
                    city = ?,
                    country = ?,
                    latitude = ?,
                    longitude = ?,
                    createdAt=Now()
                ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $aid,
            $additionalValues['phone'],
            $additionalValues['strasse'],
            $additionalValues['plz'],
            $additionalValues['ort'],
            $additionalValues['land'],
            $additionalValues['latitude'],
            $additionalValues['longitude']
        ]);
        $adid = (int)$this->db->lastInsertId();

        // Pass-Eintrag (Seriennummer für QR-Code/Terminal-Anmeldung) sofort mit anlegen
        $this->ensurePass($aid);

        return $adid;
    }
    
    public function verifyAccountByToken(string $verificationToken): string {
        $this->logger->debug('DatabaseAccountRepository::verifyAccountByToken()', [
            'verificationToken' => $verificationToken,
        ]);


        $stmt = $this->db->prepare('SELECT isVerified FROM account WHERE verificationToken = ?');
        $stmt->execute([$verificationToken]);

        $row = $stmt->fetch();

        if (!$row) {
            return AccountVerificationResult::NOT_FOUND;
        } elseif ($row['isVerified']) {
            return AccountVerificationResult::ALREADY_VERIFIED;
        }


        $stmt = $this->db->prepare('UPDATE account SET isVerified = 1 WHERE verificationToken = ?');
        $stmt->execute([$verificationToken]);

        return AccountVerificationResult::SUCCESS;
    }

    public function changePasswordHash(string $email, string $passwordHash): void {
        $this->logger->debug('DatabaseAccountRepository::changePassword()', ['email' => $email]);

        $stmt = $this->db->prepare('UPDATE account SET passwordHash = ? WHERE email = ?');
        $stmt->execute([
            $passwordHash,
            $email,
        ]);

        if ($stmt->rowCount() < 1) {
            throw new AccountNotFoundException();
        }
    }

    /**
     * @throws AccountNotFoundException
     */
    public function putPasswordResetToken(string $email, string $passwordResetToken): void {
        $this->logger->debug('DatabaseAccountRepository::putPasswordResetToken()', [
            'email' => $email,
            'passwordResetToken' => $passwordResetToken,
        ]);

        $stmt = $this->db->prepare('
            UPDATE account
            SET passwordResetToken = ?,
                passwordResetTokenExpiresAtUtc = ?
            WHERE email = ?
        ');
        $expiryTime = new DateTime(timezone: new DateTimeZone('UTC'));
        $expiryTime->modify('+1 hour');
        $stmt->execute([
            $passwordResetToken,
            $expiryTime->format('Y-m-d H:i:s'),
            $email,
        ]);

        if ($stmt->rowCount() < 1) {
            throw new AccountNotFoundException("No account found for email `$email`");
        }
    }

    public function clearPasswordResetToken(string $email): void {
        $this->logger->debug('DatabaseAccountRepository::clearPasswordResetToken()', [
            'email' => $email,
        ]);

        $stmt = $this->db->prepare(
            'UPDATE account
            SET passwordResetToken = NULL,
                passwordResetTokenExpiresAtUtc = NULL
            WHERE email = ?'
        );
        $stmt->execute([$email]);

        if ($stmt->rowCount() < 1) {
            throw new PasswordResetTokenNotFoundException();
        }
    }

    public function getEMailForPasswordResetToken(string $passwordResetToken): string {
        $this->logger->debug('DatabaseAccountRepository::getAccountIdForPasswordResetToken()', [
            'passwordResetToken' => $passwordResetToken
        ]);

        $stmt = $this->db->prepare(
            'SELECT email, passwordResetTokenExpiresAtUtc FROM account WHERE passwordResetToken = ?'
        );
        $stmt->execute([$passwordResetToken]);

        $row = $stmt->fetch();

        if (!$row) {
            throw new PasswordResetTokenNotFoundException();
        }
        if (new DateTime($row['passwordResetTokenExpiresAtUtc'], timezone: new DateTimeZone(('UTC'))) < new DateTime()) {
            throw new PasswordResetTokenExpiredException();
        }
        return $row['email'];
    }

    public function getPasswordHash(string $email,bool $isSuperAdmin = false,bool $isAppUsing = false): ?string {
        if($isSuperAdmin) {
            $query = 'SELECT passwordHash FROM admins WHERE email = ?';   
           // $this->logger->debug('DatabaseAccountRepository::getPasswordHash()', ['email' => $email,'isa' => $isSuperAdmin]);   
        }
        else {
            if($isAppUsing) {
                $query = "SELECT 
                    passwordHash 
                    FROM account 
                    WHERE isVerified = 1 
                    AND email = ? 
                    AND FIND_IN_SET('APP_USER',type) > 0
                    " ;  
            }
            else {
                $query = "SELECT 
                    passwordHash 
                    FROM account 
                    WHERE isVerified = 1 
                    AND email = ? 
                    AND FIND_IN_SET('BACKEND_USER',type) > 0
                    " ; 
            }
        }
        $stmt = $this->db->prepare($query);
        $stmt->execute([$email]);

        $row = $stmt->fetch();

        if (!$row) {
            return null;
        }
        //$this->logger->debug('DatabaseAccountRepository::getPasswordHash()', ['email' => $email,'isa' => $isSuperAdmin]);
        return $row['passwordHash'];
    }

    public function getAccountId(string $email,bool $isSuperAdmin = false): ?int {
        $this->logger->debug('DatabaseAccountRepository::getAccountId()', ['email' => $email,'isa' => $isSuperAdmin]);
        
        
        if($isSuperAdmin) {
            $query = "SELECT id FROM admins WHERE email = ?";    
        }
        else {
            $query = "SELECT id FROM account WHERE isVerified = 1 AND email = ?";
        }
        
        //$query = "SELECT id,isVerified FROM admins WHERE email = ?";    

        $stmt = $this->db->prepare($query);
        $stmt->execute([$email]);

        $row = $stmt->fetch();

        if (!$row) {
            return null;
        }
        return (int)$row['id'];
    }

    public function getAccount(int $accountId,bool $isSuperAdmin = false): ?array {
        $this->logger->debug('DatabaseAccountRepository::getAccount()', ['accountId' => $accountId]);

        if($isSuperAdmin) {
            $query = "SELECT
               *
            FROM admins
            WHERE id = ?";    
        }
        else {
            $query = "SELECT
               ac.*,
                  (SELECT bezeichnung FROM usergruppe WHERE id=ac.gruppe) as team
            FROM account AS ac
            WHERE id = ?";    
        }
        
        
        $stmt = $this->db->prepare($query);
        $stmt->execute([$accountId]);

        $row = $stmt->fetch();

        if (!$row) {
            return null;
        }
        if($isSuperAdmin) {
            $row['role'] = "ADMIN";
        }
        return $row;
    }

    public function getEinstellungen(int $accountId): array {
        $stmt = $this->db->prepare("SELECT einstellungen FROM account WHERE id = ? LIMIT 1");
        $stmt->execute([$accountId]);
        $roh = $stmt->fetchColumn();

        if (!$roh) {
            return []; // noch nie gespeichert – der Browser behält seine Werte
        }

        $werte = json_decode((string)$roh, true);
        return is_array($werte) ? $werte : [];
    }

    public function saveEinstellungen(int $accountId, array $einstellungen): void {
        $stmt = $this->db->prepare("UPDATE account SET einstellungen = ? WHERE id = ? LIMIT 1");
        $stmt->execute([json_encode($einstellungen, JSON_UNESCAPED_UNICODE), $accountId]);
    }

    public function getMitarbeiterList(int $kundenid, string $isDeleted) : array {
        
        /*
        $query = "SELECT 
                    ac.*,
                    ug.bezeichnung as gruppename
                    FROM account as ac
                    LEFT JOIN usergruppe as ug ON ac.gruppe = ug.id
                    WHERE ac.customerId = ? AND ac.isDeleted = ? 
                    ORDER BY ac.name ASC";
        */
        
        $year = date('Y'); 
                    
        $query = "SELECT
                    ac.*,
                    ug.bezeichnung as gruppename,
                    uj.jahr,uj.resturlaub,
                    uj.sonderurlaub,
                     (uj.resturlaub+jahresurlaub) AS gesamt
                    FROM account as ac
                    LEFT JOIN usergruppe as ug ON ac.gruppe = ug.id
                    LEFT JOIN urlaubjahr as uj ON ac.id = uj.uid AND uj.jahr = ?
                    WHERE ac.customerId = ?
                    AND ac.isDeleted = ?
                    ORDER BY CAST(SUBSTRING_INDEX(ac.mitarbeiternr, '-', -1) AS UNSIGNED) ASC";
        $stmt = $this->db->prepare($query);
        $stmt->execute([$year, $kundenid, $isDeleted]);
    
        $values = [];
        
        while (false != ($row = $stmt->fetch())) {
            $cid = $row['id'];
            $query = "SELECT * FROM address WHERE contactId='$cid' AND type='USER' ORDER BY id ASC LIMIT 1";
            
            $stmt2 = $this->db->prepare($query);
            $stmt2->execute();
            
            $adr = $stmt2->fetch();
            
            unset($row['passwordHash']);
            unset($row['verificationToken']);
            
            $row['address'] = $adr;

            // PKPass-Seriennummer (für QR-Code/Zugangskarten) — legt fehlende passes-Einträge nach
            $pass = $this->ensurePass((int)$cid);
            $row['serial_no'] = $pass['serial_number'];

            $values[] = $row;
        }

        return $values;
    }
    
    public function createMitarbeiter(int $kundenid, array $fields) : int {
        // erst account anlegen
        // erster Account ist der Admin      
        $password = $fields['password'];
        
        $passwordHash = password_hash($password, PASSWORD_DEFAULT);
        $verificationToken = TokenIssuer::randomStr();
        $passwordhash = $this->getPasswordHash($fields['password']);
        
        $query = "INSERT INTO account SET
                        customerId = ?,
                        mitarbeiternr = ?,
                        name = ?,
                        vorname = ?,
                        email = ?,
                        isVerified = ?,
                        passwordHash = ?,
                        verificationToken = ?,
                        createdAt=Now(),
                        username = ?,
                        type = ?,
                        role = ?,
                        accountgroupid=?,
                        
                        gruppe = ?,
                        sollstunden = ?,
                        stundensatz = ?,
                        auszahlung = ?,
                        auszahlungReeleWS = ?,
                        jahresurlaub = ?,
                        arbeitszeitmodell = ?,
                        auszahlungMonat = ?
                    ";
        
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $kundenid,
            $fields['mitarbeiternr'],
            $fields['name'],
            $fields['vorname'],
            $fields['email'],
            $fields['isVerified'],
            $passwordHash,
            $verificationToken,
            $fields['username'],
            $fields['type'],
            $fields['role'],
            $fields['accountgroupid'],
            
            $fields['gruppe'],
            $fields['sollstunden'],
            $fields['stundensatz'],
            $fields['auszahlung'],
            $fields['auszahlungReeleWS'],
            $fields['jahresurlaub'],
            $fields['arbeitszeitmodell'],
            $fields['auszahlungMonat']
        ]);
        $aid = (int)$this->db->lastInsertId();
        
        // Für geminiUrlaubsplaner urlaubjahr-Tabelle anpassen
        $query = "INSERT INTO urlaubjahr SET
                    uid = ?,
                    jahr = YEAR(NOW()),
                    jahresanspruch = ?,
                    sonderurlaub = '0',
                    resturlaub = '0'
            ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $aid,
            $fields['jahresurlaub'],   
        ]);
        
        // adresse anlegen    
        // lat/long ermitteln
        $address = $fields['address'];
        $addressline = $address['street'] . ',' . $address['postcode'] . ' ' . $address['city'] . ',' . $address['country'];
        $latlng = $this->geocoder->geocode($addressline);
        
        if($latlng) {
            $address['latitude']  = $latlng->lat;
            $address['longitude'] = $latlng->lng;   
        }
        
        // erste Adresse anlegen für kunde
        $query = "INSERT INTO address SET
                    contactId = ?,
                    type= ?,
                    zusatz = ?,
                    telefon1 = ?,
                    telefon2 = ?,
                    street = ?,
                    postcode = ?,
                    city = ?,
                    country = ?,
                    latitude = ?,
                    longitude = ?,
                    createdAt=Now()
                ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $aid,
            $address['type'],
            $address['zusatz'],
            $address['telefon1'],
            $address['telefon2'],
            $address['street'],
            $address['postcode'],
            $address['city'],
            $address['country'],
            $address['latitude'],
            $address['longitude']
        ]);
        
        $adid = (int)$this->db->lastInsertId();

        // Pass-Eintrag (Seriennummer für QR-Code/Terminal-Anmeldung) sofort mit anlegen
        $this->ensurePass($aid);

        return $aid;
    }
    
    public function checkAnmeldename(string $name, string $mitarbeiterId = '0') : bool {
        
        $query = "SELECT id FROM account 
                    WHERE username=? AND id!=? "; 
        
        $stmt = $this->db->prepare($query); 
        $stmt->execute([$name,$mitarbeiterId]);
        
        $row = $stmt->fetch();
        
        if (!$row) {
            return false;
        }
        else {
            return true;    
        }  
    }
    
    public function putMitarbeiter(int $id, array $fields) : void {
        
        if($fields) {
            
            $password = "";
            
            if(array_key_exists('password', $fields)) {
                $password = $fields['password'];
                unset($fields['password']);
            }
            
            $query = "UPDATE urlaubjahr SET
                        jahresanspruch = ?,
                        resturlaub = ?
                        WHERE uid = ? 
                        AND jahr = YEAR(NOW()) LIMIT 1
                        ";
              
            $stmt = $this->db->prepare($query);
            $stmt->execute([
                $fields['jahresurlaub'],
                $fields['resturlaub'],
                $id,
            ]);
            
            //`samstagsarbeit`, `safaktor`, `permanentimkalender`, `gruppename`, `jahr`, `resturlaub`, `sonderurlaub`, `gesamt`
            unset($fields['samstagsarbeit']);
            unset($fields['safaktor']);
            unset($fields['permanentimkalender']);
            unset($fields['gruppename']);
            unset($fields['jahr']);
            unset($fields['resturlaub']);
            unset($fields['sonderurlaub']);
            unset($fields['gesamt']);
            unset($fields['arbeitszeitmodellname']);
            unset($fields['passwordResetToken']);
            unset($fields['passwordResetTokenExpiresAtUtc']);
            
            $stmt = $this->db->prepare('UPDATE account SET '
                . SqlHelper::updatePlaceholders($fields, Account::$modifiableColumns)
                . ' WHERE id = :id');
            $fields['id'] = $id;
            $stmt->execute($fields);  
            
            $this->logger->debug('password', ['pw' => $password]);
            
            if(strlen($password) >= 8) {
                
                $passwordHash = password_hash($password, PASSWORD_DEFAULT);
                $verificationToken = TokenIssuer::randomStr();
                $passwordhash = $this->getPasswordHash($password);
                
                $query = "UPDATE account SET 
                            passwordHash = ?,
                            verificationToken = ?
                            WHERE id = ?    
                            ";
                $stmt = $this->db->prepare($query); 
                $stmt->execute([
                    $passwordHash,
                    $verificationToken,
                    $id    
                ]);
            }
        }    
    }
    
    public function patchMitarbeiter(int $id, string $isDeleted) : void {
        $query = "UPDATE account SET
                    isDeleted=?
                    WHERE id=?
                    ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([$isDeleted,$id]);         
    }
    
    private function createSerialNo() : string {
        $valid = false;
        
        while(!$valid) {
            $serialno = "";
            for($i=0;$i<7;$i++) {
                $val = bin2hex(random_bytes(1));
                $serialno .= $val;
                if( $i < 6) {
                    $serialno .= " ";
                }     
            }

            $query = "SELECT id FROM passes
                        WHERE serial_number=?
                    ";
            
            $stmt = $this->db->prepare($query); 
            $stmt->execute([$serialno]);
            
            $row = $stmt->fetch();
            
            if (!$row) { // kein ergebnis
                $valid = true;
            }
        }
        return $serialno;
    }

    /**
     * Liefert den passes-Eintrag des Accounts (id, serial_number, authentication_token).
     * Existiert noch keiner, wird er sofort angelegt — jeder Mitarbeiter muss eine
     * Seriennummer haben, da Terminal/Stempeluhr darüber an-/abmelden.
     */
    private function ensurePass(int $uid) : array {
        $query = "SELECT id,serial_number,authentication_token
                    FROM passes WHERE userid = ? LIMIT 1";

        $stmt = $this->db->prepare($query);
        $stmt->execute([$uid]);

        $row = $stmt->fetch();

        if($row) { // es gibt schon ein eintrag
            return $row;
        }

        // neue Daten generieren für passes
        $serialno   = $this->createSerialNo();
        $auth_token = bin2hex(random_bytes(16));

        $query = "INSERT INTO passes SET
                    userid = ?,
                    serial_number = ?,
                    authentication_token = ?,
                    pass_type_id = ?,
                    type = ?,
                    created_at=NOW(),
                    updated_at=NOW()
                    ";
        $stmt = $this->db->prepare($query);
        $stmt->execute([
            $uid,
            $serialno,
            $auth_token,
            $this->settings->get('pkpass')['passtype_id'],
            "PKPASS"
        ]);

        return [
            'id'                   => (int)$this->db->lastInsertId(),
            'serial_number'        => $serialno,
            'authentication_token' => $auth_token,
        ];
    }

    public function generatePass(int $id): array {
        $uid = $id;
        $result = ['status' => false];
        // Daten für user holen:
            
        $query = "SELECT 
                    ac.mitarbeiternr,
                    ac.name,
                    ac.vorname,
                    ac.email,
                    ad.street,
                    ad.postcode,
                    ad.city,
                    ad.country,
                    ac.customerid,
                    cu.id as cid,
                    cu.name AS firma,
                    cu.logourl
                    FROM account AS ac
                    LEFT JOIN address AS ad ON ad.contactId=ac.id
                    LEFT JOIN customer AS cu ON cu.id=ac.customerid
                    WHERE ac.id = ? 
                    LIMIT 1
                    ";
        $stmt = $this->db->prepare($query); 
        $stmt->execute([$uid]);
        
        $row = $stmt->fetch();
                    
        if($row) {   
            $passname      = "pass_$uid.pkpass";         
            $name          = $row['vorname'] ." " .$row['name'];
            $email         = $row['email'];
            $street        = $row['street'];
            $postcode      = $row['postcode'];
            $city          = $row['city'];
            $country       = $row['country'];
            $firma         = $row['firma'];
            $mitarbeiterno = $row['mitarbeiternr'];
            $logourl       = $row['logourl'];
            
            $passtype_id = $this->settings->get('pkpass')['passtype_id'];
            $team_id     = $this->settings->get('pkpass')['team_id'];

            // passes-Eintrag holen bzw. anlegen
            $pass = $this->ensurePass($uid);

            $pid        = $pass['id'];
            $serialno   = $pass['serial_number'];
            $auth_token = $pass['authentication_token'];

            // passdaten in array
            $data = [
                "uid"            => $uid,
                "name"           => $name,
                "mitarbeiterno"  => $mitarbeiterno,
                "email"          => $email,
                "street"         => $street,
                "postcode"       => $postcode,
                "city"           => $city,
                "country"        => $country,
                "firma"          => $firma,
                "serialno"       => $serialno,    
                "p12certificate" => $this->settings->get('pkpass')['p12certificate'],
                "p12pw"          => $this->settings->get('pkpass')['p12pw'],
                "passname"       => $passname,
                "stripe"         => $logourl,
                "webserviceurl"  => $this->settings->get('pkpass')['webserviceurl'],
                "pkpasspath"     => $this->settings->get('pkpass')['pkpasspath'],
                "passtype_id"    => $passtype_id,
                "auth_token"     => $auth_token,
                "team_id"          => $team_id,
                "description"      => $this->settings->get('pkpass')['description'],
                "logoText"         => $this->settings->get('pkpass')['logoText'],
                "organizationName" => $this->settings->get('pkpass')['organizationName'],
                "imagepath"        => $this->settings->get('pkpass')['imagepath'],
            ];
            
            // Pass generierem
            $result = $this->pkpass->generatePass($data);
            
            if($result['status']) {
                // als email an mitarbeiter versenden
                $filepath = $result['file'];
                $this->mail->sendPKPass($email, $filepath, $name);
            }
        }
        return $result;
    }
}
