<?php
if (!function_exists('next_doc_no')) {
    function next_doc_no(PDO $pdo, string $type, string $date = null): string {
        $year = $date ? (int)date('Y', strtotime($date)) : (int)date('Y');
        $pdo->beginTransaction();
        try {
            $st = $pdo->prepare(
                "SELECT id, next_val FROM doc_sequences
                 WHERE doc_type=? AND year_val=?
                 FOR UPDATE"
            );
            $st->execute([$type, $year]);
            $row = $st->fetch(PDO::FETCH_ASSOC);
            if ($row) {
                $num = (int)$row['next_val'];
                $pdo->prepare("UPDATE doc_sequences SET next_val=next_val+1 WHERE id=?")
                    ->execute([$row['id']]);
            } else {
                $num = 1;
                $pdo->prepare("INSERT INTO doc_sequences (doc_type,year_val,next_val) VALUES (?,?,2)")
                    ->execute([$type, $year]);
            }
            $pdo->commit();
            return sprintf('%s-%04d-%05d', $type, $year, $num);
        } catch (Exception $e) {
            $pdo->rollBack();
            throw $e;
        }
    }
}
