<?php
/* Copyright (C) 2026 ZUGFeRD Import Module
 *
 * 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    batch.php
 * \ingroup importzugferd
 * \brief   Batch import from folder or IMAP
 */

// 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 && file_exists("../../../main.inc.php")) {
    $res = @include "../../../main.inc.php";
}
if (!$res) {
    die("Include of main fails");
}

require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';

dol_include_once('/importzugferd/class/actions_importzugferd.class.php');
dol_include_once('/importzugferd/lib/importzugferd.lib.php');

// Load translation files
$langs->loadLangs(array("importzugferd@importzugferd", "bills", "products"));

// Security check
if (!$user->hasRight('importzugferd', 'import', 'write')) {
    accessforbidden();
}

// Get parameters
$action = GETPOST('action', 'aZ09');
$source = GETPOST('source', 'alpha');

// Initialize objects
$actions = new ActionsImportZugferd($db);

$import_results = array();
$error = 0;

/*
 * Actions
 */

// Process batch import
if ($action == 'process') {
    $auto_create = getDolGlobalString('IMPORTZUGFERD_AUTO_CREATE_INVOICE');

    if ($source == 'folder') {
        // Import from local folder
        $watch_folder = getDolGlobalString('IMPORTZUGFERD_WATCH_FOLDER');
        $archive_folder = getDolGlobalString('IMPORTZUGFERD_ARCHIVE_FOLDER');
        $error_folder = getDolGlobalString('IMPORTZUGFERD_ERROR_FOLDER');

        if (empty($watch_folder) || !is_dir($watch_folder)) {
            setEventMessages($langs->trans('ErrorWatchFolderNotConfigured'), null, 'errors');
            $error++;
        } else {
            // Create archive folder if needed
            if (!empty($archive_folder) && !is_dir($archive_folder)) {
                dol_mkdir($archive_folder);
            }
            // Create error folder if needed
            if (!empty($error_folder) && !is_dir($error_folder)) {
                dol_mkdir($error_folder);
            }

            // Get PDF files from watch folder
            $files = glob($watch_folder . '/*.pdf');
            if (empty($files)) {
                $files = glob($watch_folder . '/*.PDF');
            }

            if (!empty($files)) {
                foreach ($files as $pdf_path) {
                    $result = array(
                        'file' => basename($pdf_path),
                        'status' => 'error',
                        'message' => '',
                        'invoice_id' => 0,
                    );

                    $res = $actions->processPdf($pdf_path, $user, $auto_create);

                    if ($res > 0) {
                        $result['status'] = 'success';
                        $result['message'] = $langs->trans('ImportSuccessful');
                        $import_data = $actions->getResult();
                        $result['invoice_id'] = $import_data['invoice_id'];

                        // Move to archive
                        if (!empty($archive_folder) && is_dir($archive_folder)) {
                            $archive_path = $archive_folder . '/success_' . date('Y-m-d_His') . '_' . basename($pdf_path);
                            if (@rename($pdf_path, $archive_path) || (@copy($pdf_path, $archive_path) && @unlink($pdf_path))) {
                                $result['archived'] = true;
                            }
                        }
                    } elseif ($res == -3) {
                        // Duplicate - move to archive (already imported)
                        $result['status'] = 'skipped';
                        $result['message'] = $langs->trans('ErrorDuplicateInvoice');

                        if (!empty($archive_folder) && is_dir($archive_folder)) {
                            $archive_path = $archive_folder . '/duplicate_' . date('Y-m-d_His') . '_' . basename($pdf_path);
                            if (@rename($pdf_path, $archive_path) || (@copy($pdf_path, $archive_path) && @unlink($pdf_path))) {
                                $result['archived'] = true;
                            }
                        }
                    } else {
                        // Error - move to error folder
                        $result['message'] = $actions->error;

                        if (!empty($error_folder) && is_dir($error_folder)) {
                            $error_path = $error_folder . '/error_' . date('Y-m-d_His') . '_' . basename($pdf_path);
                            if (@rename($pdf_path, $error_path) || (@copy($pdf_path, $error_path) && @unlink($pdf_path))) {
                                $result['moved_to_error'] = true;
                            }
                        }
                    }

                    $import_results[] = $result;
                }
            } else {
                setEventMessages($langs->trans('NoFilesFound'), null, 'warnings');
            }
        }
    } elseif ($source == 'imap') {
        // Import from IMAP
        if (!function_exists('imap_open')) {
            setEventMessages($langs->trans('IMAPExtensionNotInstalled'), null, 'errors');
            $error++;
        } else {
            $host = getDolGlobalString('IMPORTZUGFERD_IMAP_HOST');
            $port = getDolGlobalString('IMPORTZUGFERD_IMAP_PORT', '993');
            $imap_user = getDolGlobalString('IMPORTZUGFERD_IMAP_USER');
            $password = getDolGlobalString('IMPORTZUGFERD_IMAP_PASSWORD');
            $ssl = getDolGlobalString('IMPORTZUGFERD_IMAP_SSL');
            $folder = getDolGlobalString('IMPORTZUGFERD_IMAP_FOLDER', 'INBOX');
            $archive_folder = getDolGlobalString('IMPORTZUGFERD_IMAP_ARCHIVE_FOLDER', 'Archive');

            if (empty($host) || empty($imap_user)) {
                setEventMessages($langs->trans('ErrorIMAPNotConfigured'), null, 'errors');
                $error++;
            } else {
                $mailbox_base = '{' . $host . ':' . $port . '/imap' . ($ssl ? '/ssl' : '') . '/novalidate-cert}';
                $mailbox = $mailbox_base . $folder;

                $connection = @imap_open($mailbox, $imap_user, $password);

                if ($connection) {
                    // Search for emails with PDF attachments
                    $emails = imap_search($connection, 'ALL');

                    if ($emails) {
                        // Create temp directory for attachments
                        $temp_dir = $conf->importzugferd->dir_output . '/temp';
                        if (!is_dir($temp_dir)) {
                            dol_mkdir($temp_dir);
                        }

                        foreach ($emails as $email_num) {
                            $structure = imap_fetchstructure($connection, $email_num);
                            $attachments = array();

                            // Find PDF attachments
                            if (isset($structure->parts)) {
                                foreach ($structure->parts as $part_num => $part) {
                                    $filename = '';
                                    if ($part->ifdparameters) {
                                        foreach ($part->dparameters as $param) {
                                            if (strtolower($param->attribute) == 'filename') {
                                                $filename = $param->value;
                                            }
                                        }
                                    }
                                    if (empty($filename) && $part->ifparameters) {
                                        foreach ($part->parameters as $param) {
                                            if (strtolower($param->attribute) == 'name') {
                                                $filename = $param->value;
                                            }
                                        }
                                    }

                                    // Check if PDF
                                    if (!empty($filename) && preg_match('/\.pdf$/i', $filename)) {
                                        $attachments[] = array(
                                            'filename' => $filename,
                                            'part_num' => $part_num + 1,
                                            'encoding' => $part->encoding,
                                        );
                                    }
                                }
                            }

                            // Process each PDF attachment
                            $email_processed = false;
                            foreach ($attachments as $attachment) {
                                $data = imap_fetchbody($connection, $email_num, $attachment['part_num']);

                                // Decode attachment
                                if ($attachment['encoding'] == 3) { // BASE64
                                    $data = base64_decode($data);
                                } elseif ($attachment['encoding'] == 4) { // QUOTED-PRINTABLE
                                    $data = quoted_printable_decode($data);
                                }

                                // Save to temp file
                                $temp_file = $temp_dir . '/' . uniqid() . '_' . $attachment['filename'];
                                file_put_contents($temp_file, $data);

                                $result = array(
                                    'file' => $attachment['filename'],
                                    'status' => 'error',
                                    'message' => '',
                                    'invoice_id' => 0,
                                );

                                // Process the PDF
                                $res = $actions->processPdf($temp_file, $user, $auto_create);

                                if ($res > 0) {
                                    $result['status'] = 'success';
                                    $result['message'] = $langs->trans('ImportSuccessful');
                                    $import_data = $actions->getResult();
                                    $result['invoice_id'] = $import_data['invoice_id'];
                                    $email_processed = true;
                                } elseif ($res == -3) {
                                    $result['status'] = 'skipped';
                                    $result['message'] = $langs->trans('ErrorDuplicateInvoice');
                                } else {
                                    $result['message'] = $actions->error;
                                }

                                // Clean up temp file
                                @unlink($temp_file);

                                $import_results[] = $result;
                            }

                            // Move email to archive folder if successfully processed
                            if ($email_processed && !empty($archive_folder)) {
                                $archive_mailbox = $mailbox_base . $archive_folder;
                                @imap_mail_move($connection, $email_num, $archive_folder);
                            }
                        }

                        // Expunge to apply moves
                        imap_expunge($connection);
                    } else {
                        setEventMessages($langs->trans('NoEmailsFound'), null, 'warnings');
                    }

                    imap_close($connection);
                } else {
                    setEventMessages($langs->trans('ConnectionFailed') . ': ' . imap_last_error(), null, 'errors');
                    $error++;
                }
            }
        }
    }

    if (!empty($import_results)) {
        $success_count = 0;
        $error_count = 0;
        $skipped_count = 0;
        foreach ($import_results as $r) {
            if ($r['status'] == 'success') $success_count++;
            elseif ($r['status'] == 'skipped') $skipped_count++;
            else $error_count++;
        }
        setEventMessages($langs->trans('BatchImportComplete', $success_count, $error_count, $skipped_count), null, 'mesgs');
    }
}

/*
 * View
 */

$form = new Form($db);

$title = $langs->trans('BatchImport');
llxHeader('', $title, '', '', 0, 0, '', '', '', 'mod-importzugferd page-batch');

print load_fiche_titre($title, '', 'fa-file-import');

// Check configuration
$watch_folder = getDolGlobalString('IMPORTZUGFERD_WATCH_FOLDER');
$imap_host = getDolGlobalString('IMPORTZUGFERD_IMAP_HOST');

if (empty($watch_folder) && empty($imap_host)) {
    print '<div class="warning">'.$langs->trans('BatchImportNotConfigured').'</div>';
    print '<br><a href="'.dol_buildpath('/importzugferd/admin/setup.php', 1).'" class="button">'.$langs->trans('ConfigureModule').'</a>';
} else {
    // Source selection
    print '<div class="fichecenter">';
    print '<div class="div-table-responsive-no-min">';
    print '<table class="noborder centpercent">';
    print '<tr class="liste_titre">';
    print '<td>'.$langs->trans('SelectSource').'</td>';
    print '</tr>';

    // Folder option
    if (!empty($watch_folder)) {
        print '<tr class="oddeven">';
        print '<td>';
        print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
        print '<input type="hidden" name="token" value="'.newToken().'">';
        print '<input type="hidden" name="action" value="process">';
        print '<input type="hidden" name="source" value="folder">';

        print '<div class="inline-block valignmiddle">';
        print '<i class="fas fa-folder fa-2x paddingright"></i>';
        print '</div>';
        print '<div class="inline-block valignmiddle">';
        print '<strong>'.$langs->trans('ImportFromFolder').'</strong><br>';
        print '<span class="opacitymedium">'.$watch_folder.'</span>';

        // Count files
        $files = glob($watch_folder . '/*.pdf');
        if (empty($files)) $files = glob($watch_folder . '/*.PDF');
        $file_count = !empty($files) ? count($files) : 0;
        print '<br><span class="badge badge-info">'.$file_count.' '.$langs->trans('Files').'</span>';

        print '</div>';
        print '<div class="inline-block valignmiddle floatright">';
        print '<input type="submit" class="button button-primary" value="'.$langs->trans('StartImport').'"'.($file_count == 0 ? ' disabled' : '').'>';
        print '</div>';

        print '</form>';
        print '</td>';
        print '</tr>';
    }

    // IMAP option
    if (!empty($imap_host)) {
        print '<tr class="oddeven">';
        print '<td>';
        print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
        print '<input type="hidden" name="token" value="'.newToken().'">';
        print '<input type="hidden" name="action" value="process">';
        print '<input type="hidden" name="source" value="imap">';

        print '<div class="inline-block valignmiddle">';
        print '<i class="fas fa-envelope fa-2x paddingright"></i>';
        print '</div>';
        print '<div class="inline-block valignmiddle">';
        print '<strong>'.$langs->trans('ImportFromIMAP').'</strong><br>';
        print '<span class="opacitymedium">'.$imap_host.' / '.getDolGlobalString('IMPORTZUGFERD_IMAP_FOLDER', 'INBOX').'</span>';
        print '</div>';
        print '<div class="inline-block valignmiddle floatright">';
        if (function_exists('imap_open')) {
            print '<input type="submit" class="button button-primary" value="'.$langs->trans('StartImport').'">';
        } else {
            print '<span class="error">'.$langs->trans('IMAPExtensionNotInstalled').'</span>';
        }
        print '</div>';

        print '</form>';
        print '</td>';
        print '</tr>';
    }

    print '</table>';
    print '</div>';
    print '</div>';

    // Show results
    if (!empty($import_results)) {
        print '<br>';
        print '<div class="div-table-responsive-no-min">';
        print '<table class="noborder centpercent">';
        print '<tr class="liste_titre">';
        print '<td>'.$langs->trans('File').'</td>';
        print '<td>'.$langs->trans('Status').'</td>';
        print '<td>'.$langs->trans('Message').'</td>';
        print '<td>'.$langs->trans('SupplierInvoice').'</td>';
        print '</tr>';

        foreach ($import_results as $result) {
            print '<tr class="oddeven">';
            print '<td>'.dol_escape_htmltag($result['file']).'</td>';
            print '<td>';
            if ($result['status'] == 'success') {
                print '<span class="badge badge-status4">'.$langs->trans('Success').'</span>';
                if (!empty($result['archived'])) {
                    print ' <i class="fas fa-archive opacitymedium" title="'.$langs->trans('Archived').'"></i>';
                }
            } elseif ($result['status'] == 'skipped') {
                print '<span class="badge badge-status1">'.$langs->trans('Skipped').'</span>';
            } else {
                print '<span class="badge badge-status8">'.$langs->trans('Error').'</span>';
            }
            print '</td>';
            print '<td>'.dol_escape_htmltag($result['message']).'</td>';
            print '<td>';
            if ($result['invoice_id'] > 0) {
                require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
                $invoice = new FactureFournisseur($db);
                $invoice->fetch($result['invoice_id']);
                print $invoice->getNomUrl(1);
            } else {
                print '-';
            }
            print '</td>';
            print '</tr>';
        }

        print '</table>';
        print '</div>';
    }
}

llxFooter();
$db->close();
