<?php
/**
 * Admin UI for personalliggare (employees, reports, audit log).
 *
 * @package Maca_Menu_List
 */

if (!defined('ABSPATH')) {
    exit;
}

if (!function_exists('maca_menulist_should_apply_personal_admin_sv')) {
    require_once __DIR__ . '/admin-personal-i18n.php';
}

/**
 * Personalliggare admin screen.
 */
class Maca_MenuList_Admin_Attendance {

    /**
     * Constructor.
     */
    public function __construct() {
        add_action('admin_init', array($this, 'handle_actions'));
        add_action('admin_init', array($this, 'maybe_export_csv'));
        add_action('admin_init', array($this, 'maybe_download_archive'));
    }

    /**
     * Active personalliggare tab (within Personal).
     *
     * @param string $tab Optional explicit tab.
     * @return string
     */
    private function get_tab($tab = '') {
        if ($tab !== '') {
            $tab = sanitize_key($tab);
        } else {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'employees';
        }

        $allowed = array('employees', 'report', 'archive', 'log');

        return in_array($tab, $allowed, true) ? $tab : 'employees';
    }

    /**
     * Build Personal admin URL for personalliggare views.
     *
     * @param array<string, string> $args Query args.
     * @return string
     */
    private function page_url($args = array()) {
        if (function_exists('maca_menulist_personal_admin_url')) {
            return maca_menulist_personal_admin_url($args);
        }

        return add_query_arg(
            array_merge(
                array('page' => 'maca-restu-personal'),
                $args
            ),
            admin_url('admin.php')
        );
    }

    /**
     * Render one personalliggare tab inside Personal.
     *
     * @param string $tab Tab slug.
     * @return void
     */
    public function render_panel($tab = '') {
        if (!maca_menulist_user_can_manage_plugin()) {
            return;
        }

        $tab = $this->get_tab($tab);

        if ($tab === 'report') {
            $this->render_report_tab();
        } elseif ($tab === 'archive') {
            $this->render_archive_tab();
        } elseif ($tab === 'log') {
            $this->render_log_tab();
        } else {
            $this->render_employees_tab();
        }
    }

    /**
     * Handle POST actions.
     *
     * @return void
     */
    public function handle_actions() {
        if (!isset($_POST['maca_attendance_action'])) {
            return;
        }

        if (!isset($_POST['maca_attendance_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maca_attendance_nonce'])), 'maca_attendance')) {
            return;
        }

        if (!maca_menulist_user_can_manage_plugin()) {
            return;
        }

        $action = sanitize_key(wp_unslash($_POST['maca_attendance_action']));

        if ($action === 'save_employee') {
            $this->handle_save_employee();
            return;
        }

        if ($action === 'reset_pin') {
            $this->handle_reset_pin();
            return;
        }

        if ($action === 'correct_times') {
            $this->handle_correct_times();
            return;
        }

        if ($action === 'save_archive_settings') {
            $this->handle_save_archive_settings();
            return;
        }

        if ($action === 'create_archive') {
            $this->handle_create_archive();
        }
    }

    /**
     * Export CSV report.
     *
     * @return void
     */
    public function maybe_export_csv() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!function_exists('maca_menulist_is_personal_admin_request') || !maca_menulist_is_personal_admin_request()) {
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_GET['maca_export']) || sanitize_key(wp_unslash($_GET['maca_export'])) !== 'csv') {
            return;
        }

        if (!maca_menulist_user_can_manage_plugin()) {
            return;
        }

        check_admin_referer('maca_attendance_export');

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $date_from = isset($_GET['date_from']) ? sanitize_text_field(wp_unslash($_GET['date_from'])) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $date_to = isset($_GET['date_to']) ? sanitize_text_field(wp_unslash($_GET['date_to'])) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $only_activity = isset($_GET['only_activity']) && sanitize_text_field(wp_unslash($_GET['only_activity'])) === '1';

        $rows = maca_menulist_build_attendance_report(
            $date_from,
            $date_to,
            array(
                'include_personal_number' => true,
                'only_with_activity' => $only_activity,
            )
        );

        $filename = 'personalliggare-' . maca_menulist_attendance_normalize_date($date_from) . '-' . maca_menulist_attendance_normalize_date($date_to) . '.csv';

        nocache_headers();
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=' . $filename);

        $out = fopen('php://output', 'w');
        if ($out === false) {
            return;
        }

        fprintf($out, chr(0xEF) . chr(0xBB) . chr(0xBF));

        fputcsv(
            $out,
            array(
                __('Date', 'maca-restu-pro'),
                __('Name', 'maca-restu-pro'),
                __('Personal identity number', 'maca-restu-pro'),
                __('In', 'maca-restu-pro'),
                __('Out', 'maca-restu-pro'),
                __('Status', 'maca-restu-pro'),
            )
        );

        foreach ($rows as $row) {
            fputcsv(
                $out,
                array(
                    (string) $row['date'],
                    (string) $row['name'],
                    (string) ($row['personal_number_display'] ?? ''),
                    (string) $row['clock_in'],
                    (string) $row['clock_out'],
                    !empty($row['is_clocked_in'])
                        ? __('Clocked in', 'maca-restu-pro')
                        : (!empty($row['had_activity']) ? __('Clocked out', 'maca-restu-pro') : __('No activity', 'maca-restu-pro')),
                )
            );
        }

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- CSV stream to php://output.
        fclose($out);
        exit;
    }

    /**
     * Download a saved monthly archive (CSV or printable HTML).
     *
     * @return void
     */
    public function maybe_download_archive() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!function_exists('maca_menulist_is_personal_admin_request') || !maca_menulist_is_personal_admin_request()) {
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_GET['maca_archive_download'])) {
            return;
        }

        if (!maca_menulist_user_can_manage_plugin()) {
            return;
        }

        check_admin_referer('maca_attendance_archive_download');

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $type = sanitize_key(wp_unslash($_GET['maca_archive_download']));
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $month = isset($_GET['month']) ? sanitize_text_field(wp_unslash($_GET['month'])) : '';

        if (!function_exists('maca_menulist_attendance_archive_get_file_path')) {
            return;
        }

        $path = maca_menulist_attendance_archive_get_file_path($month, $type);
        if ($path === '') {
            wp_die(esc_html__('Archive file not found.', 'maca-restu-pro'));
        }

        nocache_headers();

        if ($type === 'html') {
            header('Content-Type: text/html; charset=utf-8');
            header('Content-Disposition: inline; filename="' . basename($path) . '"');
        } else {
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename="' . basename($path) . '"');
        }

        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.Security.EscapeOutput.OutputNotEscaped -- Trusted local archive file stream.
        echo file_get_contents($path);
        exit;
    }

    /**
     * Save monthly archive settings.
     *
     * @return void
     */
    private function handle_save_archive_settings() {
        $enabled = !empty($_POST['archive_enabled']);
        $time = isset($_POST['archive_time']) ? sanitize_text_field(wp_unslash($_POST['archive_time'])) : '03:00';
        $retention = isset($_POST['archive_retention_months']) ? absint(wp_unslash($_POST['archive_retention_months'])) : 24;

        if (function_exists('maca_menulist_attendance_archive_save_settings')) {
            maca_menulist_attendance_archive_save_settings($enabled, $time, $retention);
        }

        add_settings_error(
            'maca_attendance',
            'archive_settings_saved',
            __('Monthly archive settings saved.', 'maca-restu-pro'),
            'success'
        );

        wp_safe_redirect($this->page_url(array('tab' => 'archive')));
        exit;
    }

    /**
     * Create archive for one month (manual).
     *
     * @return void
     */
    private function handle_create_archive() {
        $month = isset($_POST['archive_month']) ? sanitize_text_field(wp_unslash($_POST['archive_month'])) : '';

        if ($month === '' && function_exists('maca_menulist_attendance_archive_previous_month_key')) {
            $month = maca_menulist_attendance_archive_previous_month_key();
        }

        if (!function_exists('maca_menulist_attendance_archive_create_month')) {
            return;
        }

        $result = maca_menulist_attendance_archive_create_month($month, 'manual');
        add_settings_error(
            'maca_attendance',
            'archive_created',
            (string) ($result['message'] ?? ''),
            !empty($result['success']) ? 'success' : 'error'
        );

        wp_safe_redirect($this->page_url(array('tab' => 'archive')));
        exit;
    }

    /**
     * Save employee profile.
     *
     * @return void
     */
    private function handle_save_employee() {
        $employee_id = isset($_POST['employee_id']) ? absint(wp_unslash($_POST['employee_id'])) : 0;
        $name = isset($_POST['employee_name']) ? sanitize_text_field(wp_unslash($_POST['employee_name'])) : '';
        $personal_number = isset($_POST['employee_personal_number'])
            ? maca_menulist_normalize_personal_number(wp_unslash($_POST['employee_personal_number']))
            : '';
        $personal_number_type = isset($_POST['employee_personal_number_type'])
            ? sanitize_key(wp_unslash($_POST['employee_personal_number_type']))
            : 'pnr';
        $is_active = !empty($_POST['employee_is_active']);

        if ($name === '') {
            add_settings_error('maca_attendance', 'name_required', __('Enter a name.', 'maca-restu-pro'), 'error');
            return;
        }

        if (!maca_menulist_is_valid_personal_number($personal_number)) {
            add_settings_error('maca_attendance', 'pnr_invalid', __('Enter a valid personal identity number (10 or 12 digits).', 'maca-restu-pro'), 'error');
            return;
        }

        $data = array(
            'id' => $employee_id,
            'name' => $name,
            'personal_number' => $personal_number,
            'personal_number_type' => $personal_number_type,
            'is_active' => $is_active,
        );

        if ($employee_id <= 0) {
            $pin = maca_menulist_generate_employee_pin();
            $data['pin_hash'] = maca_menulist_hash_employee_pin($pin);
        }

        $saved_id = maca_menulist_db_save_employee($data);
        if ($saved_id <= 0) {
            add_settings_error('maca_attendance', 'save_failed', __('Could not save employee.', 'maca-restu-pro'), 'error');
            return;
        }

        if ($employee_id <= 0) {
            set_transient(
                'maca_attendance_new_pin_' . get_current_user_id(),
                array(
                    'employee_id' => $saved_id,
                    'pin' => $pin,
                ),
                MINUTE_IN_SECONDS
            );
        }

        wp_safe_redirect(
            $this->page_url(
                array(
                    'tab' => 'employees',
                    'employee_saved' => '1',
                    'employee_id' => (string) $saved_id,
                )
            )
        );
        exit;
    }

    /**
     * Correct attendance times for one employee/day.
     *
     * @return void
     */
    private function handle_correct_times() {
        $employee_id = isset($_POST['correct_employee_id']) ? absint(wp_unslash($_POST['correct_employee_id'])) : 0;
        $date = isset($_POST['correct_date']) ? sanitize_text_field(wp_unslash($_POST['correct_date'])) : '';
        $clock_in = isset($_POST['correct_clock_in']) ? sanitize_text_field(wp_unslash($_POST['correct_clock_in'])) : '';
        $clock_out = isset($_POST['correct_clock_out']) ? sanitize_text_field(wp_unslash($_POST['correct_clock_out'])) : '';
        $note = isset($_POST['correct_note']) ? sanitize_textarea_field(wp_unslash($_POST['correct_note'])) : '';

        $result = maca_menulist_attendance_correct_day_times($employee_id, $date, $clock_in, $clock_out, $note);

        if (!$result['success']) {
            add_settings_error('maca_attendance', 'correct_failed', $result['message'], 'error');
            wp_safe_redirect(
                $this->page_url(
                    array(
                        'tab' => 'report',
                        'correct_employee_id' => $employee_id,
                        'correct_date' => maca_menulist_attendance_normalize_date($date),
                    )
                )
            );
            exit;
        }

        add_settings_error('maca_attendance', 'correct_saved', $result['message'], 'success');

        wp_safe_redirect(
            $this->page_url(
                array(
                    'tab' => 'report',
                    'date_from' => maca_menulist_attendance_normalize_date($date),
                    'date_to' => maca_menulist_attendance_normalize_date($date),
                )
            )
        );
        exit;
    }

    /**
     * Reset employee PIN.
     *
     * @return void
     */
    private function handle_reset_pin() {
        $employee_id = isset($_POST['employee_id']) ? absint(wp_unslash($_POST['employee_id'])) : 0;
        $employee = maca_menulist_db_get_employee($employee_id);

        if (!$employee) {
            add_settings_error('maca_attendance', 'employee_missing', __('Employee not found.', 'maca-restu-pro'), 'error');
            return;
        }

        $pin = maca_menulist_generate_employee_pin();
        $saved_id = maca_menulist_db_save_employee(
            array(
                'id' => $employee_id,
                'name' => (string) $employee->name,
                'personal_number' => (string) $employee->personal_number,
                'personal_number_type' => (string) $employee->personal_number_type,
                'is_active' => (int) $employee->is_active === 1,
                'pin_hash' => maca_menulist_hash_employee_pin($pin),
            )
        );

        if ($saved_id <= 0) {
            add_settings_error('maca_attendance', 'pin_reset_failed', __('Could not reset code.', 'maca-restu-pro'), 'error');
            return;
        }

        set_transient(
            'maca_attendance_new_pin_' . get_current_user_id(),
            array(
                'employee_id' => $employee_id,
                'pin' => $pin,
            ),
            MINUTE_IN_SECONDS
        );

        wp_safe_redirect(
            $this->page_url(
                array(
                    'tab' => 'employees',
                    'pin_reset' => '1',
                    'employee_id' => (string) $employee_id,
                )
            )
        );
        exit;
    }

    /**
     * Employees tab.
     *
     * @return void
     */
    private function render_employees_tab() {
        $edit_id = isset($_GET['employee_id']) ? absint(wp_unslash($_GET['employee_id'])) : 0;
        $edit_employee = $edit_id > 0 ? maca_menulist_db_get_employee($edit_id) : null;
        $employees = maca_menulist_db_get_employees(false);
        $today_summary = maca_menulist_build_attendance_day_summary();
        $new_pin = get_transient('maca_attendance_new_pin_' . get_current_user_id());

        if (is_array($new_pin) && !empty($new_pin['pin'])) {
            delete_transient('maca_attendance_new_pin_' . get_current_user_id());
        }
        ?>
        <?php if (is_array($new_pin) && !empty($new_pin['pin'])) : ?>
            <div class="notice notice-success">
                <p>
                    <?php
                    printf(
                        /* translators: %s: personal code */
                        esc_html__('New personal code: %s — share it securely with the employee.', 'maca-restu-pro'),
                        '<strong>' . esc_html((string) $new_pin['pin']) . '</strong>'
                    );
                    ?>
                </p>
            </div>
        <?php endif; ?>

        <h2><?php esc_html_e('Today', 'maca-restu-pro'); ?></h2>
        <table class="widefat striped" style="max-width: 720px;">
            <thead>
                <tr>
                    <th><?php esc_html_e('Name', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('In', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Out', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if ($today_summary === array()) : ?>
                    <tr>
                        <td colspan="4"><?php esc_html_e('No active employees yet.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($today_summary as $row) : ?>
                        <tr>
                            <td><?php echo esc_html($row['name']); ?></td>
                            <td><?php echo esc_html($row['clock_in']); ?></td>
                            <td><?php echo esc_html($row['clock_out']); ?></td>
                            <td>
                                <?php
                                echo $row['is_clocked_in']
                                    ? esc_html__('Clocked in', 'maca-restu-pro')
                                    : esc_html__('Not clocked in', 'maca-restu-pro');
                                ?>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>

        <hr>

        <h2><?php echo $edit_employee ? esc_html__('Edit employee', 'maca-restu-pro') : esc_html__('Add employee', 'maca-restu-pro'); ?></h2>
        <form method="post" action="">
            <?php wp_nonce_field('maca_attendance', 'maca_attendance_nonce'); ?>
            <input type="hidden" name="maca_attendance_action" value="save_employee">
            <input type="hidden" name="employee_id" value="<?php echo esc_attr((string) ($edit_employee ? (int) $edit_employee->id : 0)); ?>">

            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><label for="employee_name"><?php esc_html_e('Name', 'maca-restu-pro'); ?></label></th>
                    <td><input type="text" class="regular-text" id="employee_name" name="employee_name" value="<?php echo esc_attr($edit_employee ? (string) $edit_employee->name : ''); ?>" required></td>
                </tr>
                <tr>
                    <th scope="row"><label for="employee_personal_number"><?php esc_html_e('Personal identity number', 'maca-restu-pro'); ?></label></th>
                    <td>
                        <input type="text" class="regular-text" id="employee_personal_number" name="employee_personal_number" value="<?php echo esc_attr($edit_employee ? (string) $edit_employee->personal_number : ''); ?>" required>
                        <p class="description"><?php esc_html_e('Stored for Skatteverket reports. 10 or 12 digits.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="employee_personal_number_type"><?php esc_html_e('ID type', 'maca-restu-pro'); ?></label></th>
                    <td>
                        <select id="employee_personal_number_type" name="employee_personal_number_type">
                            <?php
                            $type = $edit_employee ? (string) $edit_employee->personal_number_type : 'pnr';
                            $options = array(
                                'pnr' => __('Personnummer', 'maca-restu-pro'),
                                'coordination' => __('Samordningsnummer', 'maca-restu-pro'),
                                'foreign' => __('Foreign ID', 'maca-restu-pro'),
                            );
                            foreach ($options as $value => $label) :
                                ?>
                                <option value="<?php echo esc_attr($value); ?>" <?php selected($type, $value); ?>><?php echo esc_html($label); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e('Active', 'maca-restu-pro'); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="employee_is_active" value="1" <?php checked(!$edit_employee || (int) $edit_employee->is_active === 1); ?>>
                            <?php esc_html_e('Can clock in/out', 'maca-restu-pro'); ?>
                        </label>
                    </td>
                </tr>
            </table>

            <?php submit_button($edit_employee ? __('Save employee', 'maca-restu-pro') : __('Add employee', 'maca-restu-pro')); ?>
        </form>

        <?php if ($edit_employee) : ?>
            <form method="post" action="" style="margin-top: -8px;">
                <?php wp_nonce_field('maca_attendance', 'maca_attendance_nonce'); ?>
                <input type="hidden" name="maca_attendance_action" value="reset_pin">
                <input type="hidden" name="employee_id" value="<?php echo esc_attr((string) (int) $edit_employee->id); ?>">
                <?php submit_button(__('Generate new personal code', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
            </form>
            <p><a href="<?php echo esc_url($this->page_url(array('tab' => 'employees'))); ?>"><?php esc_html_e('Add new employee', 'maca-restu-pro'); ?></a></p>
        <?php endif; ?>

        <h2><?php esc_html_e('Employees', 'maca-restu-pro'); ?></h2>
        <table class="widefat striped" style="max-width: 960px;">
            <thead>
                <tr>
                    <th><?php esc_html_e('Name', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Personal identity number', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Active', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if ($employees === array()) : ?>
                    <tr>
                        <td colspan="4"><?php esc_html_e('No employees yet.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($employees as $employee) : ?>
                        <tr>
                            <td><?php echo esc_html((string) $employee->name); ?></td>
                            <td><?php echo esc_html(maca_menulist_mask_personal_number((string) $employee->personal_number)); ?></td>
                            <td><?php echo (int) $employee->is_active === 1 ? esc_html__('Yes', 'maca-restu-pro') : esc_html__('No', 'maca-restu-pro'); ?></td>
                            <td>
                                <a href="<?php echo esc_url($this->page_url(array('tab' => 'employees', 'employee_id' => (int) $employee->id))); ?>">
                                    <?php esc_html_e('Edit', 'maca-restu-pro'); ?>
                                </a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Report tab.
     *
     * @return void
     */
    private function render_report_tab() {
        $today = function_exists('maca_menulist_wp_today') ? maca_menulist_wp_today() : wp_date('Y-m-d');
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $date_from = isset($_GET['date_from']) ? sanitize_text_field(wp_unslash($_GET['date_from'])) : $today;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $date_to = isset($_GET['date_to']) ? sanitize_text_field(wp_unslash($_GET['date_to'])) : $today;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $only_activity = isset($_GET['only_activity']) && sanitize_text_field(wp_unslash($_GET['only_activity'])) === '1';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $correct_employee_id = isset($_GET['correct_employee_id']) ? absint(wp_unslash($_GET['correct_employee_id'])) : 0;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $correct_date = isset($_GET['correct_date']) ? sanitize_text_field(wp_unslash($_GET['correct_date'])) : '';

        if ($correct_employee_id > 0 && $correct_date !== '') {
            $this->render_correction_form($correct_employee_id, $correct_date, $date_from, $date_to, $only_activity);
            return;
        }

        $rows = maca_menulist_build_attendance_report(
            $date_from,
            $date_to,
            array(
                'include_personal_number' => true,
                'only_with_activity' => $only_activity,
            )
        );

        $export_url = wp_nonce_url(
            $this->page_url(
                array(
                    'tab' => 'report',
                    'maca_export' => 'csv',
                    'date_from' => maca_menulist_attendance_normalize_date($date_from),
                    'date_to' => maca_menulist_attendance_normalize_date($date_to),
                    'only_activity' => $only_activity ? '1' : '0',
                )
            ),
            'maca_attendance_export'
        );
        ?>
        <h2><?php esc_html_e('Attendance report', 'maca-restu-pro'); ?></h2>
        <p class="description"><?php esc_html_e('Full report with personal identity numbers for archive and Skatteverket inspection. Use Correct to fix times — every change is logged.', 'maca-restu-pro'); ?></p>

        <form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" class="maca-attendance-report-filters" style="margin: 16px 0;">
            <input type="hidden" name="page" value="<?php echo esc_attr(function_exists('maca_menulist_personal_admin_page') ? maca_menulist_personal_admin_page() : 'maca-restu-personal'); ?>">
            <input type="hidden" name="tab" value="report">
            <label>
                <?php esc_html_e('From', 'maca-restu-pro'); ?>
                <input type="date" name="date_from" value="<?php echo esc_attr(maca_menulist_attendance_normalize_date($date_from)); ?>">
            </label>
            <label style="margin-left: 12px;">
                <?php esc_html_e('To', 'maca-restu-pro'); ?>
                <input type="date" name="date_to" value="<?php echo esc_attr(maca_menulist_attendance_normalize_date($date_to)); ?>">
            </label>
            <label style="margin-left: 12px;">
                <input type="checkbox" name="only_activity" value="1" <?php checked($only_activity); ?>>
                <?php esc_html_e('Only days with clock activity', 'maca-restu-pro'); ?>
            </label>
            <?php submit_button(__('Filter', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
            <a href="<?php echo esc_url($export_url); ?>" class="button button-primary" style="margin-left: 8px;"><?php esc_html_e('Export CSV', 'maca-restu-pro'); ?></a>
            <button type="button" class="button" style="margin-left: 8px;" onclick="window.print();"><?php esc_html_e('Print', 'maca-restu-pro'); ?></button>
        </form>

        <table class="widefat striped maca-attendance-admin-report">
            <thead>
                <tr>
                    <th><?php esc_html_e('Date', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Name', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Personal identity number', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('In', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Out', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if ($rows === array()) : ?>
                    <tr>
                        <td colspan="7"><?php esc_html_e('No rows match the filter.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($rows as $row) : ?>
                        <tr>
                            <td><?php echo esc_html((string) $row['date']); ?></td>
                            <td><?php echo esc_html((string) $row['name']); ?></td>
                            <td><?php echo esc_html((string) ($row['personal_number_display'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) $row['clock_in']); ?></td>
                            <td><?php echo esc_html((string) $row['clock_out']); ?></td>
                            <td>
                                <?php
                                if (!empty($row['is_clocked_in'])) {
                                    esc_html_e('Clocked in', 'maca-restu-pro');
                                } elseif (!empty($row['had_activity'])) {
                                    esc_html_e('Clocked out', 'maca-restu-pro');
                                } else {
                                    esc_html_e('No activity', 'maca-restu-pro');
                                }
                                ?>
                            </td>
                            <td>
                                <a href="<?php echo esc_url($this->page_url(array(
                                    'tab' => 'report',
                                    'date_from' => maca_menulist_attendance_normalize_date($date_from),
                                    'date_to' => maca_menulist_attendance_normalize_date($date_to),
                                    'only_activity' => $only_activity ? '1' : '0',
                                    'correct_employee_id' => (int) $row['employee_id'],
                                    'correct_date' => (string) $row['date'],
                                ))); ?>">
                                    <?php esc_html_e('Correct', 'maca-restu-pro'); ?>
                                </a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Correction form for one employee/day.
     *
     * @param int    $employee_id Employee ID.
     * @param string $date        Date Y-m-d.
     * @param string $date_from   Report filter from.
     * @param string $date_to     Report filter to.
     * @param bool   $only_activity Report filter flag.
     * @return void
     */
    private function render_correction_form($employee_id, $date, $date_from, $date_to, $only_activity) {
        $employee = maca_menulist_db_get_employee($employee_id);
        if (!$employee) {
            echo '<p>' . esc_html__('Employee not found.', 'maca-restu-pro') . '</p>';
            return;
        }

        $date = maca_menulist_attendance_normalize_date($date);
        $slots = maca_menulist_attendance_get_day_slot_events($employee_id, $date);
        $clock_in_value = $slots['clock_in']
            ? maca_menulist_attendance_time_input_value((string) $slots['clock_in']->occurred_at)
            : '';
        $clock_out_value = $slots['clock_out']
            ? maca_menulist_attendance_time_input_value((string) $slots['clock_out']->occurred_at)
            : '';

        $back_url = $this->page_url(
            array(
                'tab' => 'report',
                'date_from' => maca_menulist_attendance_normalize_date($date_from),
                'date_to' => maca_menulist_attendance_normalize_date($date_to),
                'only_activity' => $only_activity ? '1' : '0',
            )
        );
        ?>
        <p><a href="<?php echo esc_url($back_url); ?>">&larr; <?php esc_html_e('Back to report', 'maca-restu-pro'); ?></a></p>

        <h2><?php esc_html_e('Correct attendance', 'maca-restu-pro'); ?></h2>
        <p class="description"><?php esc_html_e('Changes are saved with before/after values in the change log. Leave a field blank only if you do not want to change that time.', 'maca-restu-pro'); ?></p>

        <form method="post" action="" class="maca-attendance-correction-form" style="max-width: 640px;">
            <?php wp_nonce_field('maca_attendance', 'maca_attendance_nonce'); ?>
            <input type="hidden" name="maca_attendance_action" value="correct_times">
            <input type="hidden" name="correct_employee_id" value="<?php echo esc_attr((string) $employee_id); ?>">
            <input type="hidden" name="correct_date" value="<?php echo esc_attr($date); ?>">

            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><?php esc_html_e('Employee', 'maca-restu-pro'); ?></th>
                    <td><strong><?php echo esc_html((string) $employee->name); ?></strong></td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e('Date', 'maca-restu-pro'); ?></th>
                    <td><?php echo esc_html($date); ?></td>
                </tr>
                <tr>
                    <th scope="row"><label for="correct_clock_in"><?php esc_html_e('Clock in', 'maca-restu-pro'); ?></label></th>
                    <td>
                        <input type="time" id="correct_clock_in" name="correct_clock_in" value="<?php echo esc_attr($clock_in_value); ?>">
                        <p class="description"><?php esc_html_e('Set or correct start time. Required if adding a missing clock-in.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="correct_clock_out"><?php esc_html_e('Clock out', 'maca-restu-pro'); ?></label></th>
                    <td>
                        <input type="time" id="correct_clock_out" name="correct_clock_out" value="<?php echo esc_attr($clock_out_value); ?>">
                        <p class="description"><?php esc_html_e('Set or correct end time. Required if adding a missing clock-out.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="correct_note"><?php esc_html_e('Note (optional)', 'maca-restu-pro'); ?></label></th>
                    <td>
                        <textarea id="correct_note" name="correct_note" rows="2" class="large-text" placeholder="<?php esc_attr_e('e.g. Forgot to clock out', 'maca-restu-pro'); ?>"></textarea>
                    </td>
                </tr>
            </table>

            <?php submit_button(__('Save correction', 'maca-restu-pro')); ?>
        </form>
        <?php
    }

    /**
     * Monthly archive tab.
     *
     * @return void
     */
    private function render_archive_tab() {
        $enabled = function_exists('maca_menulist_attendance_archive_enabled')
            ? maca_menulist_attendance_archive_enabled()
            : false;
        $time = function_exists('maca_menulist_attendance_archive_get_run_time')
            ? maca_menulist_attendance_archive_get_run_time()
            : '03:00';
        $retention = function_exists('maca_menulist_attendance_archive_get_retention_months')
            ? maca_menulist_attendance_archive_get_retention_months()
            : 24;
        $index = function_exists('maca_menulist_attendance_archive_get_index')
            ? maca_menulist_attendance_archive_get_index()
            : array();
        $last_run = get_option('maca_menulist_attendance_archive_last_run', '');
        $last_month = get_option('maca_menulist_attendance_archive_last_month', '');
        $next_cron = defined('MACA_MENULIST_ATTENDANCE_ARCHIVE_CRON_HOOK')
            ? wp_next_scheduled(MACA_MENULIST_ATTENDANCE_ARCHIVE_CRON_HOOK)
            : false;
        $default_month = function_exists('maca_menulist_attendance_archive_previous_month_key')
            ? maca_menulist_attendance_archive_previous_month_key()
            : wp_date('Y-m');
        ?>
        <h2><?php esc_html_e('Monthly archive', 'maca-restu-pro'); ?></h2>
        <p class="description">
            <?php esc_html_e('Saves a full monthly report (CSV + printable HTML) on the server. Files are stored under uploads and are only available to administrators — not via direct web links.', 'maca-restu-pro'); ?>
        </p>

        <form method="post" action="" style="max-width: 640px; margin: 16px 0 24px;">
            <?php wp_nonce_field('maca_attendance', 'maca_attendance_nonce'); ?>
            <input type="hidden" name="maca_attendance_action" value="save_archive_settings">
            <table class="form-table" role="presentation">
                <tr>
                    <th scope="row"><?php esc_html_e('Automatic archive', 'maca-restu-pro'); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="archive_enabled" value="1" <?php checked($enabled); ?>>
                            <?php esc_html_e('Create archive on the 1st of each month for the previous month', 'maca-restu-pro'); ?>
                        </label>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e('Run time', 'maca-restu-pro'); ?></th>
                    <td>
                        <input type="time" name="archive_time" value="<?php echo esc_attr($time); ?>">
                        <p class="description"><?php esc_html_e('Site timezone. Default: 03:00 on the 1st.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e('Retention', 'maca-restu-pro'); ?></th>
                    <td>
                        <input type="number" name="archive_retention_months" value="<?php echo esc_attr((string) $retention); ?>" min="12" max="120" step="1" class="small-text">
                        <?php esc_html_e('months', 'maca-restu-pro'); ?>
                        <p class="description"><?php esc_html_e('Skatteverket requires at least 24 months. Older archives are deleted automatically.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
            </table>
            <?php submit_button(__('Save archive settings', 'maca-restu-pro')); ?>
        </form>

        <?php if ($enabled && $next_cron) : ?>
            <p>
                <?php
                printf(
                    /* translators: %s: date and time */
                    esc_html__('Next automatic archive: %s', 'maca-restu-pro'),
                    esc_html(wp_date(get_option('date_format') . ' ' . get_option('time_format'), $next_cron))
                );
                ?>
            </p>
        <?php endif; ?>

        <?php if (is_string($last_run) && $last_run !== '') : ?>
            <p>
                <?php
                printf(
                    /* translators: 1: month key, 2: date and time */
                    esc_html__('Last archive: %1$s (%2$s)', 'maca-restu-pro'),
                    esc_html((string) $last_month),
                    esc_html(maca_menulist_format_wp_datetime($last_run))
                );
                ?>
            </p>
        <?php endif; ?>

        <form method="post" action="" style="margin: 0 0 24px;">
            <?php wp_nonce_field('maca_attendance', 'maca_attendance_nonce'); ?>
            <input type="hidden" name="maca_attendance_action" value="create_archive">
            <label>
                <?php esc_html_e('Create archive now for month', 'maca-restu-pro'); ?>
                <input type="month" name="archive_month" value="<?php echo esc_attr($default_month); ?>">
            </label>
            <?php submit_button(__('Create archive', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
        </form>

        <h3><?php esc_html_e('Saved archives', 'maca-restu-pro'); ?></h3>
        <table class="widefat striped" style="max-width: 960px;">
            <thead>
                <tr>
                    <th><?php esc_html_e('Month', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Period', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Rows', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Created', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if ($index === array()) : ?>
                    <tr>
                        <td colspan="5"><?php esc_html_e('No monthly archives yet.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($index as $entry) : ?>
                        <?php
                        if (!is_array($entry)) {
                            continue;
                        }
                        $month = (string) ($entry['month'] ?? '');
                        $csv_url = wp_nonce_url(
                            $this->page_url(
                                array(
                                    'tab' => 'archive',
                                    'maca_archive_download' => 'csv',
                                    'month' => $month,
                                )
                            ),
                            'maca_attendance_archive_download'
                        );
                        $html_url = wp_nonce_url(
                            $this->page_url(
                                array(
                                    'tab' => 'archive',
                                    'maca_archive_download' => 'html',
                                    'month' => $month,
                                )
                            ),
                            'maca_attendance_archive_download'
                        );
                        ?>
                        <tr>
                            <td><?php echo esc_html($month); ?></td>
                            <td>
                                <?php
                                echo esc_html(
                                    sprintf(
                                        '%s – %s',
                                        (string) ($entry['date_from'] ?? ''),
                                        (string) ($entry['date_to'] ?? '')
                                    )
                                );
                                ?>
                            </td>
                            <td><?php echo esc_html((string) (int) ($entry['row_count'] ?? 0)); ?></td>
                            <td><?php echo esc_html(maca_menulist_format_wp_datetime((string) ($entry['created_at'] ?? ''))); ?></td>
                            <td>
                                <a href="<?php echo esc_url($csv_url); ?>"><?php esc_html_e('Download CSV', 'maca-restu-pro'); ?></a>
                                ·
                                <a href="<?php echo esc_url($html_url); ?>" target="_blank" rel="noopener"><?php esc_html_e('Open printable report', 'maca-restu-pro'); ?></a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Change log tab.
     *
     * @return void
     */
    private function render_log_tab() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $paged = isset($_GET['paged']) ? max(1, absint(wp_unslash($_GET['paged']))) : 1;
        $per_page = 100;
        $total = maca_menulist_attendance_log_count();
        $entries = maca_menulist_attendance_log_list(
            array(
                'per_page' => $per_page,
                'paged' => $paged,
            )
        );
        $total_pages = max(1, (int) ceil($total / $per_page));
        ?>
        <h2><?php esc_html_e('Change log', 'maca-restu-pro'); ?></h2>
        <p class="description"><?php esc_html_e('All clock events and future corrections are logged here.', 'maca-restu-pro'); ?></p>

        <table class="widefat striped">
            <thead>
                <tr>
                    <th><?php esc_html_e('When', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Employee', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Action', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Changed by', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Details', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if ($entries === array()) : ?>
                    <tr>
                        <td colspan="5"><?php esc_html_e('No log entries yet.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($entries as $entry) : ?>
                        <?php
                        $changes = maca_menulist_attendance_log_decode_changes((string) ($entry->changes ?? ''));
                        $details = array();
                        foreach ($changes as $change) {
                            if (!is_array($change)) {
                                continue;
                            }
                            $label = isset($change['label']) ? (string) $change['label'] : '';
                            $old = isset($change['old']) ? (string) $change['old'] : '';
                            $new = isset($change['new']) ? (string) $change['new'] : '';
                            if ($old === '' && $new !== '') {
                                $details[] = $label . ': ' . $new;
                            } elseif ($old !== '' && $new !== '') {
                                $details[] = $label . ': ' . $old . ' → ' . $new;
                            }
                        }
                        ?>
                        <tr>
                            <td><?php echo esc_html((string) $entry->created_at); ?></td>
                            <td><?php echo esc_html((string) ($entry->employee_name ?? '')); ?></td>
                            <td>
                                <?php
                                $action_labels = array(
                                    'created' => __('Created', 'maca-restu-pro'),
                                    'corrected' => __('Corrected', 'maca-restu-pro'),
                                    'voided' => __('Voided', 'maca-restu-pro'),
                                );
                                $action_key = (string) $entry->action;
                                echo esc_html($action_labels[$action_key] ?? $action_key);
                                ?>
                            </td>
                            <td><?php echo esc_html((string) ($entry->actor_label ?? '')); ?></td>
                            <td><?php echo esc_html($details !== array() ? implode('; ', $details) : (string) ($entry->summary ?? '')); ?></td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>

        <?php if ($total_pages > 1) : ?>
            <div class="tablenav bottom">
                <div class="tablenav-pages">
                    <?php
                    echo wp_kses_post(
                        paginate_links(
                            array(
                                'base' => add_query_arg('paged', '%#%'),
                                'format' => '',
                                'prev_text' => '&laquo;',
                                'next_text' => '&raquo;',
                                'total' => $total_pages,
                                'current' => $paged,
                            )
                        )
                    );
                    ?>
                </div>
            </div>
        <?php endif; ?>
        <?php
    }
}
