<?php
// Plugin Check / PHPCS: category-level exclusions with reasons.
// Line-level findings in this file are handled individually below.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- PaintOps keeps its records in its own custom tables (built by paintops_table()); $wpdb is the supported API for plugin-owned tables, there is no core CRUD alternative, and results are request-scoped.
// phpcs:disable WordPress.DateTime.RestrictedFunctions.date_date -- date() here is deliberately paired with current_time() timestamps: crews are scheduled on the site's local calendar day, and gmdate() would shift jobs across midnight UTC.
/**
 * Included File: Today's Crew Widget
 *
 * A dashboard glance at what's happening today: which jobs/quotes are
 * on for today, who (if anyone) is assigned to each, and who's marked
 * off. Deliberately data-driven rather than assuming every install has
 * a "crew", a solo painter with no separate Painter/Helper accounts
 * will simply never see worker badges or an "off today" line, since
 * those sections only render when reqWorkers/time-off data actually
 * exists. No solo-vs-team branching needed; it just reflects whatever
 * is really in the schedule.
 *
 * Reuses the exact same duration/date-range logic as calendar.php (a
 * Job spans reqDays, a Quote is always a single day) so "today" here
 * always agrees with what the calendar grid would show for today.
 */

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

if (!function_exists('paintops_today_local')) {
    /**
     * The site-local calendar date, computed ONCE per request. Every
     * "is this today?" comparison on a page must use this, otherwise a
     * page rendered while the site's clock crosses midnight computes
     * different todays in different sections (Mike 2026-07-24: the Today
     * widget said nothing scheduled while a job card lower on the same
     * page said Started Today).
     */
    function paintops_today_local(): string {
        static $paintops_today_cache = null;
        if ($paintops_today_cache === null) {
            $paintops_today_cache = gmdate('Y-m-d', current_time('timestamp'));
        }
        return $paintops_today_cache;
    }
}

function paintops_render_todays_crew_widget(): string {
    global $wpdb;

    $today = paintops_today_local();
    $todayYear = (int) substr($today, 0, 4);

    $jobs_table = paintops_table('jobs');

    $todays_jobs = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM %i
         WHERE TO_DAYS(DATE_ADD(CONCAT(startYear, '-', LPAD(startMonth, 2, '0'), '-', LPAD(startDay, 2, '0')), INTERVAL IF(jobType = 2, GREATEST(reqDays, 1) - 1, 0) DAY)) >= TO_DAYS(%s)
           AND TO_DAYS(CONCAT(startYear, '-', LPAD(startMonth, 2, '0'), '-', LPAD(startDay, 2, '0'))) <= TO_DAYS(%s)
         ORDER BY startTime ASC", $jobs_table, $today, $today));

    // Who's marked off today, if anyone, same repeat/range handling as
    // the timeoff block in calendar.php, just narrowed to a single day.
    $timeoff_rows = $wpdb->get_results( $wpdb->prepare("SELECT user_id, day, month, year, daysOff, isRepeat FROM %i", paintops_table('timeoff')) );
    $off_today_ids = [];

    foreach ($timeoff_rows as $entry) {
        $userIds = paintops_parse_worker_ids($entry->user_id);
        $daysOff = max((int) $entry->daysOff, 1);
        $isRepeat = (bool) $entry->isRepeat;
        $startYear = $isRepeat ? $todayYear : (int) $entry->year;
        $start = mktime(0, 0, 0, (int) $entry->month, (int) $entry->day, $startYear);

        for ($i = 0; $i < $daysOff; $i++) {
            if (date('Y-m-d', strtotime("+{$i} day", $start)) === $today) {
                foreach ($userIds as $uid) {
                    $off_today_ids[] = (int) $uid;
                }
                break;
            }
        }
    }
    $off_today_ids = array_unique($off_today_ids);

    $off_today_names = [];
    foreach ($off_today_ids as $uid) {
        $user = get_userdata($uid);
        if ($user) {
            $off_today_names[] = $user->display_name;
        }
    }

    // Widget CSS through the styles API (wp.org review 2026-07); was a
    // literal <style> block in the captured template below
    // (assets/css/todays-crew-widget.css).
    paintops_enqueue_style('todays-crew-widget');

    ob_start();
    ?>
    <div class="cs-financial-box">
        <div class="job-form-section" style="margin-bottom:12px;">Today - <?php echo esc_html(date('l, F j', strtotime(paintops_today_local()))); ?></div>

        <?php if (empty($todays_jobs)) : ?>
            <p style="color:#777;margin:0;">Nothing scheduled today.</p>
        <?php else : ?>
            <?php foreach ($todays_jobs as $job) :
                $category = function_exists('paintops_get_category_details') ? (string) paintops_get_category_details((int) $job->jobCat, 0) : '';
                $label = function_exists('paintops_job_record_label')
                    ? paintops_job_record_label((int) $job->jobType, (int) ($job->isBid ?? 0), (string) ($job->quote_label ?? 'quote'))
                    : (((int) $job->jobType === 2) ? 'Job' : 'Quote');
                $custName = trim($job->custFirst . ' ' . $job->custLast);
                // Same schedule line the job view shows ("Jul 18th, 2026
                // 07:00 for 4 days"), so a multi-day job spanning today
                // shows when it actually started and how long it runs
                // (Mike 2026-07-22). Shared builder, see job-view.php.
                $schedText = function_exists('paintops_job_scheduled_text')
                    ? paintops_job_scheduled_text($job)
                    : '';
                $timeDisplay = '';
                if ($schedText === '' && !empty($job->startTime) && preg_match('/^\d{1,2}:\d{2}$/', trim($job->startTime))) {
                    $timeDisplay = date('g:i A', strtotime($job->startTime));
                }

                $workerIds = paintops_parse_worker_ids($job->reqWorkers);
                $workerNames = [];
                foreach ($workerIds as $wid) {
                    $u = get_userdata((int) $wid);
                    if ($u) {
                        $workerNames[] = $u->display_name;
                    }
                }
            ?>
                <div class="paintops-today-row">
                    <a href="<?php echo esc_url(paintops_admin_url(['viewEid' => (int) $job->id])); ?>">
                        <?php echo esc_html(trim($label . ': ' . trim($category . ' ' . $job->jobTitle))); ?>
                    </a>
                    <?php if ($custName !== '') : ?> &middot; <?php echo esc_html($custName); ?><?php endif; ?>
                    <?php if ($schedText !== '') : ?>
                        <br><span class="paintops-today-time">Scheduled: <?php echo esc_html($schedText); ?></span>
                    <?php elseif ($timeDisplay !== '') : ?> <span class="paintops-today-time">@ <?php echo esc_html($timeDisplay); ?></span><?php endif; ?>
                    <?php if (!empty($workerNames)) : ?>
                        <br><?php foreach ($workerNames as $name) : ?><span class="paintops-today-worker"><?php echo esc_html($name); ?></span><?php endforeach; ?>
                    <?php endif; ?>
                </div>
            <?php endforeach; ?>
        <?php endif; ?>

        <?php if (!empty($off_today_names)) : ?>
            <p class="paintops-today-off">Off today: <?php echo esc_html(implode(', ', $off_today_names)); ?></p>
        <?php endif; ?>
    </div>
    <?php
    return ob_get_clean();
}
