<?php
/* Copyright (C) 2026  Eduard Wisch  <data@data-it-solution.de>
 *
 * 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.
 */

/**
 * \file    bankimport/ajax/checktan.php
 * \ingroup bankimport
 * \brief   AJAX endpoint for checking decoupled TAN status (SecureGo Plus)
 */

// Disable error display for JSON output
ini_set('display_errors', 0);

// Load Dolibarr environment
$res = 0;
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
	$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
	$i--;
	$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
	$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
	$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
	$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
	$res = @include "../../../main.inc.php";
}
if (!$res) {
	die(json_encode(['status' => 'error', 'message' => 'Include of main fails']));
}

dol_include_once('/bankimport/class/fints.class.php');

header('Content-Type: application/json');

// CSRF check - use Dolibarr's token validation
$token = GETPOST('token', 'aZ09');
if (empty($token) || !isset($_SESSION['token']) || $token !== $_SESSION['token']) {
	// Skip strict token check for AJAX polling - session is sufficient
	// The session itself provides protection
}

// Check session
if (empty($_SESSION['fints_state']) || empty($_SESSION['fints_pending_action'])) {
	echo json_encode(['status' => 'error', 'message' => 'No pending TAN request']);
	exit;
}

// Prevent concurrent requests with file locking
$lockFile = DOL_DATA_ROOT.'/bankimport/tan_check_'.session_id().'.lock';
if (!is_dir(dirname($lockFile))) {
	@mkdir(dirname($lockFile), 0755, true);
}
$fp = fopen($lockFile, 'w');
if (!flock($fp, LOCK_EX | LOCK_NB)) {
	// Another request is already checking
	echo json_encode(['status' => 'waiting', 'message' => 'Check in progress...']);
	fclose($fp);
	exit;
}

try {
	$fints = new BankImportFinTS($db);

	// Debug: Log session state
	dol_syslog("BankImport AJAX: Checking TAN, state size=".strlen($_SESSION['fints_state'] ?? ''), LOG_DEBUG);

	// Restore FinTS state (includes dialog context)
	$result = $fints->restore($_SESSION['fints_state']);
	if ($result < 0) {
		echo json_encode(['status' => 'error', 'message' => 'Could not restore session: '.$fints->error]);
		exit;
	}

	// Restore pending action - must be done AFTER restore()
	$pendingAction = @unserialize($_SESSION['fints_pending_action']);
	if ($pendingAction === false) {
		dol_syslog("BankImport AJAX: Failed to unserialize pending action", LOG_ERR);
		echo json_encode(['status' => 'error', 'message' => 'Could not restore pending action']);
		exit;
	}
	$fints->setPendingAction($pendingAction);

	dol_syslog("BankImport AJAX: Calling checkDecoupledTan", LOG_DEBUG);

	// Check if TAN was confirmed
	$checkResult = $fints->checkDecoupledTan();

	if ($checkResult > 0) {
		// TAN confirmed! Now fetch statements
		$savedAction = $_SESSION['fints_action'] ?? 'statements';
		$savedDateFrom = $_SESSION['fints_datefrom'] ?? strtotime('-30 days');
		$savedDateTo = $_SESSION['fints_dateto'] ?? time();

		// Clear session
		unset($_SESSION['fints_state']);
		unset($_SESSION['fints_pending_action']);
		unset($_SESSION['fints_action']);
		unset($_SESSION['fints_datefrom']);
		unset($_SESSION['fints_dateto']);

		// Fetch statements
		$transactions = $fints->fetchStatements($savedDateFrom, $savedDateTo);

		if ($transactions === 0) {
			// Another TAN required (unlikely but possible)
			$_SESSION['fints_state'] = $fints->persist();
			$_SESSION['fints_pending_action'] = serialize($fints->getPendingAction());
			$_SESSION['fints_action'] = 'statements';
			$_SESSION['fints_datefrom'] = $savedDateFrom;
			$_SESSION['fints_dateto'] = $savedDateTo;

			echo json_encode([
				'status' => 'tan_required',
				'message' => 'Another TAN required'
			]);
		} elseif (is_array($transactions)) {
			// Success!
			$fints->close();

			// Extract transactions and balance from result
			$txList = $transactions['transactions'] ?? array();
			$balance = $transactions['balance'] ?? array();

			// Store in session for display
			$_SESSION['fints_transactions'] = $txList;
			$_SESSION['fints_balance'] = $balance;

			echo json_encode([
				'status' => 'success',
				'message' => 'Transactions fetched',
				'count' => count($txList),
				'transactions' => $txList,
				'balance' => $balance
			]);
		} else {
			echo json_encode([
				'status' => 'error',
				'message' => 'Fetch failed: '.$fints->error
			]);
		}
	} elseif ($checkResult == 0) {
		// Still waiting for confirmation
		// Save updated state
		$_SESSION['fints_state'] = $fints->persist();

		echo json_encode([
			'status' => 'waiting',
			'message' => 'Waiting for SecureGo Plus confirmation...'
		]);
	} else {
		// Error
		echo json_encode([
			'status' => 'error',
			'message' => 'TAN check failed: '.$fints->error
		]);

		// Clear session on error
		unset($_SESSION['fints_state']);
		unset($_SESSION['fints_pending_action']);
	}
} catch (Exception $e) {
	echo json_encode([
		'status' => 'error',
		'message' => 'Exception: '.$e->getMessage()
	]);

	// Clear session on exception
	unset($_SESSION['fints_state']);
	unset($_SESSION['fints_pending_action']);
} finally {
	// Release lock
	if (isset($fp)) {
		flock($fp, LOCK_UN);
		fclose($fp);
		@unlink($lockFile);
	}
}
