<?php
if (!defined('ABSPATH')) exit;

function ioh_render_office_hours_html(array $settings, string $style, string $loc, array $display = []): string {
    $template = (string)($settings['display']['template_html'] ?? '{{OFFICE_HOURS}}');
    $base = ioh_render_office_hours_base_html($settings, $style, $loc, $display);

    $tpl = ioh_normalize_office_hours_template($template);
    if (strpos($tpl, '{{OFFICE_HOURS}}') === false) $tpl .= '{{OFFICE_HOURS}}';
    $tpl = str_replace('{{OFFICE_HOURS}}', $base, $tpl);
    $tpl = str_replace('{{LOCATION}}', esc_html($loc), $tpl);

    // Wrap in a container to protect against theme styles
    return '<div class="ioh-template-wrap">' . $tpl . '</div>';
}

function ioh_normalize_office_hours_template(string $template): string {
    $legacy_default = '<div style="font-family: system-ui; color:#000;"><div style="font-weight:700; font-size:18px; margin:0 0 10px;">Office Hours</div>{{OFFICE_HOURS}}</div>';
    if (preg_replace('/\s+/', '', $template) === preg_replace('/\s+/', '', $legacy_default)) {
        return '{{OFFICE_HOURS}}';
    }

    return $template;
}

function ioh_sanitize_shortcode_color($color): string {
    $color = strtolower(trim(sanitize_text_field((string)$color)));
    if ($color === '' || $color === 'black') return '#000000';
    if ($color === 'white') return '#ffffff';
    if (preg_match('/^#[0-9a-f]{3}([0-9a-f]{3})?$/', $color)) return $color;
    if (preg_match('/^rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/', $color)) return $color;
    return '#000000';
}

function ioh_sanitize_shortcode_size($size): string {
    $size = strtolower(trim(sanitize_text_field((string)$size)));
    if ($size === '') return '16px';
    if (preg_match('/^\d{1,3}(?:\.\d{1,2})?(px|rem|em)$/', $size)) return $size;
    return '16px';
}

function ioh_sanitize_shortcode_spacing($size): string {
    $size = strtolower(trim(sanitize_text_field((string)$size)));
    if ($size === '') return '0px';
    if (preg_match('/^-?\d{1,3}(?:\.\d{1,2})?(px|rem|em)$/', $size)) return $size;
    return '0px';
}

function ioh_shortcode_spacing_css(string $property, string $value): string {
    $value = ioh_sanitize_shortcode_spacing($value);
    if (strpos($value, '-') === 0) {
        $side = $property === 'padding-top' ? 'top' : 'bottom';
        return $property . ':0 !important; margin-' . $side . ':' . esc_html($value) . ' !important;';
    }
    return $property . ':' . esc_html($value) . ' !important;';
}

function ioh_sanitize_shortcode_text_transform($transform): string {
    $transform = strtolower(trim(sanitize_text_field((string)$transform)));
    return in_array($transform, ['uppercase', 'lowercase'], true) ? $transform : 'none';
}

function ioh_render_office_hours_base_html(array $settings, string $style, string $loc, array $display = []): string {
    $rows = ioh_build_rows_for_location($settings, $loc);
    $day_items = ioh_build_display_day_items($settings, $rows, $display);

    $title = (string)($settings['locations'][$loc]['office_hours_title'] ?? '');
    $show_title = !empty($settings['display']['show_title']);
    $show_seps  = !empty($settings['display']['show_separators']);
    $color = ioh_sanitize_shortcode_color($display['color'] ?? 'black');
    $font_size = ioh_sanitize_shortcode_size($display['size'] ?? '16px');
    $top_padding = ioh_sanitize_shortcode_spacing($display['top_padding'] ?? '0px');
    $bottom_padding = ioh_sanitize_shortcode_spacing($display['bottom_padding'] ?? '0px');
    $spacing_css = ioh_shortcode_spacing_css('padding-top', $top_padding) . ioh_shortcode_spacing_css('padding-bottom', $bottom_padding);
    $text_transform = ioh_sanitize_shortcode_text_transform($display['text_transform'] ?? 'none');
    $bold_days = !empty($display['bold_days']);
    $day_weight = $bold_days ? '700' : '400';

    // Simple neutral CSS (no theme inheritance required)
    $css = '<style>
      .ioh-template-wrap, .ioh-template-wrap *{box-sizing:border-box;}
      .ioh-office-hours{color:' . esc_html($color) . ' !important; font-family:"Raleway", sans-serif; font-size:' . esc_html($font_size) . '; line-height:1.4; max-width:100%; ' . $spacing_css . ' text-transform:' . esc_html($text_transform) . '; white-space:normal !important;}
      .ioh-office-hours, .ioh-office-hours *{color:' . esc_html($color) . ' !important; white-space:normal !important; background:transparent !important;}
      .ioh-office-hours pre, .ioh-office-hours code{background:transparent !important; padding:0 !important; margin:0 !important; border:0 !important; font-family:inherit !important; white-space:normal !important; color:inherit !important;}
      .ioh-office-hours .ioh-title{font-weight:700; letter-spacing:.02em; margin:0 0 10px;}
      .ioh-office-hours .ioh-row{display:flex; gap:10px; align-items:baseline; justify-content:space-between; padding:4px 0; min-width:0;}
      .ioh-office-hours .ioh-day{font-weight:' . esc_html($day_weight) . ' !important; margin:0; padding:0; flex:0 0 auto;}
      .ioh-office-hours .ioh-hours{margin:0; padding:0; flex:1 1 auto; text-align:right; min-width:0;}
      .ioh-office-hours .ioh-hours .ioh-line{display:block; margin:0;}
      .ioh-office-hours .ioh-sep{border:0; border-top:1px solid rgba(0,0,0,.18); margin:10px 0;}
      .ioh-office-hours table{width:100%; border-collapse:collapse;}
      .ioh-office-hours td{padding:4px 8px; vertical-align:top;}
      .ioh-office-hours td.ioh-td-day{font-weight:' . esc_html($day_weight) . ' !important; white-space:nowrap;}
      @media (max-width: 520px){
        .ioh-office-hours .ioh-row{flex-direction:column; align-items:flex-start;}
        .ioh-office-hours .ioh-hours{text-align:left;}
        .ioh-office-hours td.ioh-td-day{white-space:normal;}
      }
    </style>';

    if ($style === 'table') {
        $html = $css . '<div class="ioh-office-hours ioh-office-hours--table">';
        if ($show_title && trim($title) !== '') $html .= '<div class="ioh-title">' . esc_html($title) . '</div>';
        $html .= '<table aria-label="Office hours">';
        foreach ($day_items as $item) {
            $r = $item['row'];
            $html .= '<tr><td class="ioh-td-day">' . esc_html($item['label']) . '</td><td>' . esc_html($r['single']) . '</td></tr>';
        }
        $html .= '</table></div>';
        return $html;
    }

    if ($style === 'stacked') {
        $html = $css . '<div class="ioh-office-hours ioh-office-hours--stacked">';
        if ($show_title && trim($title) !== '') $html .= '<div class="ioh-title">' . esc_html($title) . '</div>';

        $last_index = count($day_items) - 1;
        foreach ($day_items as $index => $item) {
            $html .= '<div class="ioh-row" style="justify-content:flex-start;"><div class="ioh-day">' . esc_html($item['label']) . '</div></div>';
            foreach ($item['row']['lines'] as $line) {
                $html .= '<div class="ioh-row" style="padding-top:0; justify-content:flex-start;"><div class="ioh-hours" style="text-align:left;">' . esc_html($line) . '</div></div>';
            }

            if ($show_seps && $index < $last_index) $html .= '<hr class="ioh-sep" />';
        }
        $html .= '</div>';
        return $html;
    }

    // list default
    $html = $css . '<div class="ioh-office-hours ioh-office-hours--list">';
    if ($show_title && trim($title) !== '') $html .= '<div class="ioh-title">' . esc_html($title) . '</div>';

    foreach ($day_items as $item) {
        $r = $item['row'];
        $html .= '<div class="ioh-row"><div class="ioh-day">' . esc_html($item['label']) . '</div><div class="ioh-hours">';
        foreach ($r['lines'] as $line) $html .= '<span class="ioh-line">' . esc_html($line) . '</span>';
        $html .= '</div></div>';
    }
    $html .= '</div>';
    return $html;
}

function ioh_render_office_hours_sidebar_html(array $settings, string $loc, array $display = []): string {
    $rows = ioh_build_rows_for_location($settings, $loc);
    $day_items = ioh_build_display_day_items($settings, $rows, $display);
    $title = (string)($settings['locations'][$loc]['office_hours_title'] ?? '');
    $show_title = !empty($settings['display']['show_title']);
    $color = ioh_sanitize_shortcode_color($display['color'] ?? 'black');
    $title_color = ioh_sanitize_shortcode_color($display['title_color'] ?? $display['color'] ?? '#578ea7');
    $font_size = ioh_sanitize_shortcode_size($display['size'] ?? '15px');
    $title_size = ioh_sanitize_shortcode_size($display['title_size'] ?? '20px');
    $top_padding = ioh_sanitize_shortcode_spacing($display['top_padding'] ?? '0px');
    $bottom_padding = ioh_sanitize_shortcode_spacing($display['bottom_padding'] ?? '0px');
    $spacing_css = ioh_shortcode_spacing_css('padding-top', $top_padding) . ioh_shortcode_spacing_css('padding-bottom', $bottom_padding);
    $text_transform = ioh_sanitize_shortcode_text_transform($display['text_transform'] ?? 'none');
    $bold_days = !empty($display['bold_days']);
    $day_weight = $bold_days ? '700' : '400';

    $css = '<style>
      .ioh-sidebar-hours, .ioh-sidebar-hours *{box-sizing:border-box;}
      .ioh-sidebar-hours{font-family:"Raleway", sans-serif; color:' . esc_html($color) . ' !important; font-size:' . esc_html($font_size) . '; line-height:20px; ' . $spacing_css . ' text-align:center; text-transform:' . esc_html($text_transform) . '; max-width:100%;}
      .ioh-sidebar-hours, .ioh-sidebar-hours *{color:' . esc_html($color) . ' !important; background:transparent !important;}
      .ioh-sidebar-hours .ioh-sidebar-title{color:' . esc_html($title_color) . ' !important; font-size:' . esc_html($title_size) . '; font-weight:700; margin:0 0 16px; line-height:1.25;}
      .ioh-sidebar-hours .ioh-sidebar-row{margin:14px 0; text-align:center; line-height:20px;}
      .ioh-sidebar-hours .ioh-sidebar-day{display:block; font-weight:' . esc_html($day_weight) . ' !important;}
      .ioh-sidebar-hours .ioh-sidebar-line{display:block;}
      .ioh-sidebar-hours .ioh-sidebar-sep{display:block; height:1px; margin:5px 50px; border:0 !important; color:#ccc !important; background:#ccc !important;}
    </style>';

    $html = $css . '<div class="ioh-sidebar-hours">';
    if ($show_title && trim($title) !== '') {
        $html .= '<p class="ioh-sidebar-title"><strong>' . esc_html($title) . '</strong></p>';
        $html .= '<hr class="ioh-sidebar-sep" />';
    }

    $last_index = count($day_items) - 1;
    foreach ($day_items as $index => $item) {
        $html .= '<p class="ioh-sidebar-row"><span class="ioh-sidebar-day">' . esc_html($item['label']) . '</span>';
        foreach ($item['row']['lines'] as $line) {
            $html .= '<span class="ioh-sidebar-line">' . esc_html($line) . '</span>';
        }
        $html .= '</p>';
        if ($index < $last_index) $html .= '<hr class="ioh-sidebar-sep" />';
    }

    $html .= '</div>';
    return '<div class="ioh-template-wrap">' . $html . '</div>';
}

function ioh_render_office_hours_compact_html(array $settings, string $loc, array $display = []): string {
    $rows = ioh_build_rows_for_location($settings, $loc);
    $day_items = ioh_build_display_day_items($settings, $rows, $display);
    $color = ioh_sanitize_shortcode_color($display['color'] ?? 'black');
    $font_size = ioh_sanitize_shortcode_size($display['size'] ?? '16px');
    $top_padding = ioh_sanitize_shortcode_spacing($display['top_padding'] ?? '0px');
    $bottom_padding = ioh_sanitize_shortcode_spacing($display['bottom_padding'] ?? '0px');
    $spacing_css = ioh_shortcode_spacing_css('padding-top', $top_padding) . ioh_shortcode_spacing_css('padding-bottom', $bottom_padding);
    $text_transform = ioh_sanitize_shortcode_text_transform($display['text_transform'] ?? 'none');
    $bold_days = !empty($display['bold_days']);
    $day_weight = $bold_days ? '700' : '400';
    $labels = [
        'mon' => 'M',
        'tue' => 'T',
        'wed' => 'W',
        'thu' => 'T',
        'fri' => 'F',
        'sat' => 'S',
        'sun' => 'S',
    ];

    $css = '<style>
      .ioh-compact-hours, .ioh-compact-hours *{box-sizing:border-box;}
      .ioh-compact-hours{font-family:"Raleway", sans-serif; color:' . esc_html($color) . ' !important; font-size:' . esc_html($font_size) . '; line-height:1.45; ' . $spacing_css . ' text-transform:' . esc_html($text_transform) . '; max-width:100%;}
      .ioh-compact-hours, .ioh-compact-hours *{color:' . esc_html($color) . ' !important; background:transparent !important;}
      .ioh-compact-hours .ioh-compact-row{display:block; margin:0 0 2px;}
      .ioh-compact-hours .ioh-compact-day{font-weight:' . esc_html($day_weight) . ' !important;}
    </style>';

    $html = $css . '<div class="ioh-compact-hours">';
    foreach ($day_items as $item) {
        $label = $item['key'] === 'weekend' ? 'Saturday & Sunday' : ($labels[$item['key']] ?? $item['label']);
        $html .= '<div class="ioh-compact-row"><span class="ioh-compact-day">' . esc_html($label) . ':</span> ' . esc_html($item['row']['single']) . '</div>';
    }
    $html .= '</div>';

    return '<div class="ioh-template-wrap">' . $html . '</div>';
}

function ioh_should_capitalize_day_names(array $settings, array $display = []): bool {
    return !empty($display['capitalize_day_names']);
}

function ioh_should_capitalize_hours(array $settings, array $display = []): bool {
    return !empty($display['capitalize_hours']);
}

function ioh_format_day_label(string $label, array $settings, array $display = []): string {
    return ioh_should_capitalize_day_names($settings, $display) ? strtoupper($label) : $label;
}

function ioh_format_hours_row_for_display(array $row, array $settings, array $display = []): array {
    if (!ioh_should_capitalize_hours($settings, $display) || (($row['source'] ?? '') === 'message')) return $row;

    $row['lines'] = array_map('strtoupper', (array)($row['lines'] ?? []));
    $row['single'] = implode(' / ', $row['lines']);
    return $row;
}

function ioh_build_display_day_items(array $settings, array $rows, array $display = []): array {
    $days = ioh_days();
    $combine_weekend = !empty($display['combine_closed_weekend']);
    $can_combine_weekend = $combine_weekend
        && !empty($rows['sat']['closed'])
        && !empty($rows['sun']['closed']);

    $items = [];
    foreach ($days as $day_key => $label) {
        if ($can_combine_weekend && $day_key === 'sat') {
            $items[] = [
                'key' => 'weekend',
                'label' => ioh_format_day_label('Saturday & Sunday', $settings, $display),
                'row' => ioh_format_hours_row_for_display($rows['sat'], $settings, $display),
            ];
            continue;
        }

        if ($can_combine_weekend && $day_key === 'sun') continue;

        $items[] = [
            'key' => $day_key,
            'label' => ioh_format_day_label($label, $settings, $display),
            'row' => ioh_format_hours_row_for_display($rows[$day_key], $settings, $display),
        ];
    }

    return $items;
}

function ioh_build_rows_for_location(array $settings, string $loc): array {
    $hours = $settings['locations'][$loc]['hours'] ?? [];
    $out = [];

    foreach (ioh_days() as $d => $label) {
        $day = $hours[$d] ?? [];
        $closed = !empty($day['closed']);
        $lines = [];
        $source = 'hours';

        if ($closed) {
            $lines = ['Closed'];
            $source = 'closed';
        } elseif (trim((string)($day['message'] ?? '')) !== '') {
            $lines = [sanitize_text_field((string)$day['message'])];
            $source = 'message';
        } else {
            $r1 = ioh_fmt_range($day['r1_start'] ?? '', $day['r1_end'] ?? '');
            if ($r1) $lines[] = $r1;

            if (trim((string)($day['r2_start'] ?? '')) !== '' && trim((string)($day['r2_end'] ?? '')) !== '') {
                $r2 = ioh_fmt_range($day['r2_start'] ?? '', $day['r2_end'] ?? '');
                if ($r2) $lines[] = $r2;
            }

            if (!$lines) {
                $lines = ['Closed'];
                $source = 'closed';
            }
        }

        $out[$d] = [
            'closed' => $closed,
            'lines'  => $lines,
            'single' => implode(' / ', $lines),
            'source' => $source,
        ];
    }
    return $out;
}

function ioh_fmt_range(string $start, string $end): string {
    $start = trim($start); $end = trim($end);
    if ($start === '' || $end === '') return '';
    $ts = strtotime('1970-01-01 ' . $start . ':00');
    $te = strtotime('1970-01-01 ' . $end . ':00');
    if ($ts === false || $te === false) return '';
    return date_i18n('g:ia', $ts) . ' - ' . date_i18n('g:ia', $te);
}
