"""HTML template builder for KML popup descriptions.

Generates compact HTML tables compatible with Google Earth.
Uses a shared <style> block to minimize per-feature byte cost.
"""

import html as html_lib


class HtmlTemplateBuilder:
    """Builds HTML popup content for KML descriptions."""

    # Shared CSS block — written once per feature, not once per row
    _CSS = (
        '<style>'
        'body{font-family:sans-serif;margin:0;padding:0}'
        'table{width:100%;border-collapse:collapse;'
        'background:#fff;border:1px solid #ccc}'
        'td,th{padding:5px 8px;border:1px solid #eee}'
        'th{text-align:center;font-size:14px}'
        'td.l{color:#555;font-weight:bold;width:40%}'
        'td.hl{font-weight:bold}'
        '</style>'
    )

    def __init__(self, config):
        self.config = config

    def build(self, feature_data):
        """Build compact HTML popup for a single feature."""
        header = self.config.get('header', {})
        desc_fields = self.config.get('description_fields', [])
        row_highlights = self.config.get('row_highlights', {})

        active_fields = [f for f in desc_fields
                         if f.get('enabled', True)]
        active_fields.sort(key=lambda x: x.get('order', 999))

        h_bg = header.get('bg_color', '#1B5E20')
        h_color = header.get('text_color', '#FFFFFF')
        h_title = self._escape(header.get('title', 'Thông tin'))

        lines = [
            '<div style="min-width:220px;max-width:380px">',
            self._CSS,
            '<table>',
            f'<tr><th style="background:{h_bg};color:{h_color}">'
            f'{h_title}</th></tr>',
        ]

        for field_cfg in active_fields:
            field_name = field_cfg.get('field', '')
            alias = field_cfg.get('alias', field_name)
            suffix = field_cfg.get('suffix', '')
            value = feature_data.get(field_name, None)

            if value is not None and str(value).strip() not in (
                    '', 'NULL', 'None', 'null'):
                display_value = self._escape(str(value))
                if suffix:
                    display_value += f' {self._escape(suffix)}'
            else:
                display_value = '—'

            hl = self._get_row_highlight_style(
                field_name, value, row_highlights)

            if hl:
                tc = hl['text_color']
                bg = hl['bg_color']
                bold = 'font-weight:bold;' if hl.get('bold', True) else ''
                tr_open = f'<tr style="background:{bg}">'
                td_l = (f'<td class="l" style="color:{tc};{bold}'
                        f'border:1px solid #ddd">')
                td_v = (f'<td style="color:{tc};{bold}'
                        f'border:1px solid #ddd">')
            else:
                tr_open = '<tr>'
                td_l = '<td class="l">'
                td_v = '<td>'

            lines.append(
                f'{tr_open}{td_l}{self._escape(alias)}</td>'
                f'{td_v}{display_value}</td></tr>')

        lines.append('</table></div>')
        return ''.join(lines)

    def _get_row_highlight_style(self, field_name, value, row_highlights):
        if not row_highlights.get('enabled', False):
            return None
        for rule in row_highlights.get('rules', []):
            if rule.get('field', '') != field_name:
                continue
            if self._evaluate_condition(
                    value, rule.get('operator', '='),
                    rule.get('value', '')):
                return {
                    'text_color': rule.get('text_color', '#C62828'),
                    'bg_color': rule.get('bg_color', '#FFF5F5'),
                    'bold': rule.get('bold', True),
                }
        return None

    @staticmethod
    def _evaluate_condition(actual, operator, expected):
        if actual is None:
            return False
        actual_str = str(actual).strip()
        expected_str = str(expected).strip()
        if operator == '=':
            return actual_str == expected_str
        try:
            a_num = float(actual_str)
            e_num = float(expected_str)
            if operator == '>':
                return a_num > e_num
            elif operator == '>=':
                return a_num >= e_num
            elif operator == '<':
                return a_num < e_num
            elif operator == '<=':
                return a_num <= e_num
            elif operator == '!=':
                return a_num != e_num
        except (ValueError, TypeError):
            if operator == '>':
                return actual_str > expected_str
            elif operator == '<':
                return actual_str < expected_str
        return False

    @staticmethod
    def _escape(text):
        return html_lib.escape(str(text))
