<?php

declare(strict_types=1);

namespace Cin\Quickpurchase\service;

use Cin\Quickpurchase\classes\PurchaseArticle;
use JTL\Customer\Customer;

final class OfferService
{
  /**
   * Check if the defined daily offer limit has been reached.
   */
  public static function dailyOfferCountReached(): bool
  {
    $P = PurchaseService::Plugin();

    if ( ! isset($_SESSION['Kunde']) || false === (bool) $_SESSION['Kunde']->nRegistriert) {
      return true;
    }

    $prep = $P->getPDO()->prepare('SELECT COUNT(*) AS count FROM `xplugin_cin_purchaseportal_email_cap` WHERE `kKunde` = :kKunde AND DATE(`submitted`) = CURDATE()');
    $prep->execute([
      ':kKunde' => $_SESSION['Kunde']->kKunde
    ]);

    return $prep->fetch()->count >= $P->cfg()['cin_ankauf_mail_limit'];
  }

  public static function getCustomerItems(int $kKunde): array
  {
    $lastDays = 4;

    $prep = PurchaseService::Plugin()->getPDO()->prepare(
      'SELECT
      oa.*,
      o.created,
      o.name,
      o.surname
      FROM `xplugin_cin_purchaseportal_offer_article` oa
      LEFT JOIN `xplugin_cin_purchaseportal_offer` o ON o.case_id = oa.case_id
      WHERE o.kKunde = :kKunde
      AND o.created >= (now() - INTERVAL :days day)
      ORDER BY o.created DESC'
    );
    $prep->execute([
      ':kKunde' => $kKunde,
      ':days'   => $lastDays
    ]);

    return $prep->fetchAll();
  }

  public static function getNextCaseID(?string $prefix = null, int $start = -1, int $padcount = -1, bool $reserve = true): string
  {
    $P        = PurchaseService::Plugin();
    $prefix   = $prefix ?? $P->cfg()['cin_ankauf_case_prefix'];
    $start    = $start > -1 ? $start : (int) $P->cfg()['startindex'];
    $padcount = $padcount > -1 ? $padcount : (int) $P->cfg()['casenumberpad'];
    // $stmt     = 'SELECT id
    //   FROM xplugin_cin_purchaseportal_case_count
    //   WHERE prefix = :prefix
    //   ORDER BY id DESC
    //   LIMIT 1';
    $getNextId = 'SELECT
      CASE
        WHEN COUNT(*) = 0 THEN GREATEST(1, :start)
        ELSE GREATEST(MAX(`id`) + 1, :start1)
      END AS \'id\'
      FROM xplugin_cin_purchaseportal_case_count
      WHERE prefix = :prefix
      ORDER BY id DESC
      LIMIT 1';
    $reserveNextId = 'INSERT INTO `xplugin_cin_purchaseportal_case_count`
      (`prefix`, `id`)
      VALUES (:prefix, :id)';

    $P->getPDO()->beginTransaction();
    $prepNextId = $P->getPDO()->prepare($getNextId);
    $prepNextId->execute([
      ':prefix' => $prefix,
      ':start'  => $start,
      ':start1' => $start
    ]);
    $freeId = $prepNextId->fetchColumn();
    if ($reserve) {
      $prepReserve = $P->getPDO()->prepare($reserveNextId);
      $prepReserve->execute([
        ':prefix' => $prefix,
        ':id'     => $freeId
      ]);
    }
    $P->getPDO()->commit();

    // $id    = ((int) $prep->fetchColumn());
    $idStr = mb_str_pad(
      (string) $freeId,
      // (string) max((int) $start, (int) $freeId),
      $padcount,
      '0',
      \STR_PAD_LEFT
    );

    return ($prefix ? $prefix.'-' : '').$idStr;
  }

  public static function store(Customer $customer, string $caseID, string $payment = ''): void
  {
    $prep = PurchaseService::Plugin()->getPDO()->prepare('INSERT INTO `xplugin_cin_purchaseportal_offer`
        (`case_id`, `name`, `surname`, `street`, `number`, `zip`, `place`, `state`, `country`, `customer_id`, `kKunde`, `mail`, `payment_method`)
        VALUES (:case_id, :name, :surname, :street, :number, :zip, :place, :state, :country, :customer_id, :kKunde, :mail, :payment_method)');

    $prep->execute([
      ':case_id'        => $caseID,
      ':name'           => $customer->cVorname,
      ':surname'        => $customer->cNachname,
      ':street'         => $customer->cStrasse,
      ':number'         => $customer->cHausnummer,
      ':zip'            => $customer->cPLZ,
      ':place'          => $customer->cOrt,
      ':state'          => $customer->cBundesland,
      ':country'        => $customer->cLand,
      ':customer_id'    => $customer->cKundenNr,
      ':kKunde'         => $customer->kKunde,
      ':mail'           => MailingService::encrypt_mail($customer->cMail),
      ':payment_method' => $payment
    ]);
  }

  public static function storeArticle(string $caseID, PurchaseArticle $purchaseArticle, mixed $calculatedPrice, int $conditionID, int $queue_id = 0): void
  {
    $prep = PurchaseService::Plugin()->getPDO()->prepare('INSERT INTO `xplugin_cin_purchaseportal_offer_article`
               (`case_id`, `manufacturer_iso_2`, `kArtikel`, `cArtNr`, `cHAN`, `cName`, `fVKNetto`, `fVKBrutto`, `custom_description`, `quantity`, `direct_purchase`, `purchase_price`, `condition_history_id`, `queue_id`)
        VALUES (:case_id, :manufacturer_iso_2, :kArtikel, :cArtNr, :cHAN, :cName, :fVKNetto, :fVKBrutto, :description, :quantity, :direct_purchase, :purchase_price, :condition_history_id, :queue_id)');

    $prep->execute([
      ':case_id'             => $caseID,
      ':manufacturer_iso_2'  => mb_substr($purchaseArticle->cArtNr, 0, 2),
      ':kArtikel'            => $purchaseArticle->kArtikel,
      ':cArtNr'              => $purchaseArticle->cArtNr,
      ':cHAN'                => $purchaseArticle->cHAN,
      ':cName'               => $purchaseArticle->cName,
      ':fVKNetto'            => $purchaseArticle->fVKNetto,
      ':fVKBrutto'           => $purchaseArticle->fVKBrutto,
      ':description'         => $purchaseArticle->custom_description,
      ':quantity'            => $purchaseArticle->quantity,
      ':direct_purchase'     => $purchaseArticle->direct_purchase,
      'purchase_price'       => $calculatedPrice,
      'condition_history_id' => $conditionID,
      'queue_id'             => $queue_id
    ]);
  }

  /**
   * store used numeric part of case id.
   */
  public static function tickCaseID(string $caseid): void
  {
    $partials = explode('-', $caseid);
    $P        = PurchaseService::Plugin();

    // $P->getPDO()->prepare(
    //   'INSERT INTO `xplugin_cin_purchaseportal_case_count`
    //   (`prefix`, `id`)
    //   VALUES (:prefix, :id)'
    // )
    $P->getPDO()->prepare(
      'UPDATE `xplugin_cin_purchaseportal_case_count` SET
        `reserved` = 0
        WHERE `prefix` = :prefix
        AND `id` = :id'
    )
      ->execute([
        ':prefix' => 2 === \count($partials) ? $partials[0] : '',
        ':id'     => (int) $partials[(bool) (2 === \count($partials))]
      ]);
  }
}
