# -*- coding: utf-8 -*-
"""
Load Vietnamese administrative boundaries from local GeoJSON files.
Two levels: province (Cap Tinh) and commune (Cap Xa).
"""

import json
import os

_PLUGIN_DIR = os.path.dirname(os.path.dirname(__file__))
_BOUNDARY_DIR = os.path.join(_PLUGIN_DIR, 'boundary')
_PROVINCE_FILE = os.path.join(_BOUNDARY_DIR, 'DiaPhan_CapTinh_2025.json')
_COMMUNE_FILE = os.path.join(_BOUNDARY_DIR, 'DiaPhan_CapXa_2025.json')

_cache = {
    'provinces': None,
    'communes_by_ma_tinh': None,
    'province_features': None,
    'commune_features': None,
}


def _load_geojson(path):
    with open(path, 'r', encoding='utf-8') as handle:
        return json.load(handle)


def is_boundaries_loaded():
    return _cache['provinces'] is not None


def _report(progress_callback, value, message):
    if progress_callback is not None:
        progress_callback(value, message)


def ensure_boundaries_loaded(progress_callback=None):
    if _cache['provinces'] is not None:
        _report(progress_callback, 100, '')
        return

    _report(progress_callback, 5, u'Reading province boundaries... / Đang đọc ranh giới tỉnh...')
    province_data = _load_geojson(_PROVINCE_FILE)
    _report(progress_callback, 35, u'Reading commune boundaries... / Đang đọc ranh giới xã...')

    commune_data = _load_geojson(_COMMUNE_FILE)
    _report(progress_callback, 55, u'Building province list... / Đang lập danh sách tỉnh...')

    provinces = []
    province_features = {}
    for feature in province_data.get('features', []):
        props = feature.get('properties', {})
        ma_tinh = props.get('maTinh')
        ten_tinh = props.get('tenTinh', '')
        if ma_tinh is None:
            continue
        ma_tinh = str(ma_tinh)
        provinces.append({'maTinh': ma_tinh, 'tenTinh': ten_tinh})
        province_features[ma_tinh] = feature

    provinces.sort(key=lambda item: item['tenTinh'])
    _report(progress_callback, 75, u'Building commune list... / Đang lập danh sách xã...')

    communes_by_ma_tinh = {}
    commune_features = {}
    for feature in commune_data.get('features', []):
        props = feature.get('properties', {})
        ma_tinh = props.get('maTinh')
        ma_xa = props.get('maXa')
        ten_xa = props.get('tenXa', '')
        if ma_tinh is None or ma_xa is None:
            continue
        ma_tinh = str(ma_tinh)
        ma_xa = str(ma_xa)
        commune = {'maXa': ma_xa, 'tenXa': ten_xa, 'maTinh': ma_tinh}
        communes_by_ma_tinh.setdefault(ma_tinh, []).append(commune)
        commune_features[ma_xa] = feature

    for communes in communes_by_ma_tinh.values():
        communes.sort(key=lambda item: item['tenXa'])

    _cache['provinces'] = provinces
    _cache['province_features'] = province_features
    _cache['communes_by_ma_tinh'] = communes_by_ma_tinh
    _cache['commune_features'] = commune_features
    _report(progress_callback, 100, u'Ready / Sẵn sàng')


def _ensure_loaded():
    ensure_boundaries_loaded()


def get_provinces():
    """Return sorted list of provinces with maTinh and tenTinh."""
    _ensure_loaded()
    return _cache['provinces']


def get_communes_by_province(ma_tinh):
    """Return communes belonging to a province."""
    _ensure_loaded()
    return _cache['communes_by_ma_tinh'].get(str(ma_tinh), [])


def build_boundary_geojson(ma_tinh, ma_xa=None):
    """
    Build a GeoJSON FeatureCollection for the selected administrative unit.

    :param ma_tinh: Province code (maTinh).
    :param ma_xa: Commune code (maXa). If None, return the whole province boundary.
    """
    _ensure_loaded()

    if ma_xa is None:
        feature = _cache['province_features'].get(str(ma_tinh))
        if feature is None:
            raise ValueError('Province not found: {}'.format(ma_tinh))
        return {'type': 'FeatureCollection', 'features': [feature]}

    feature = _cache['commune_features'].get(str(ma_xa))
    if feature is None:
        raise ValueError('Commune not found: {}'.format(ma_xa))
    return {'type': 'FeatureCollection', 'features': [feature]}


def get_boundary_name(ma_tinh, ma_xa=None):
    """Return display name for export filenames."""
    _ensure_loaded()
    province = next(
        (item for item in _cache['provinces'] if item['maTinh'] == str(ma_tinh)),
        None,
    )
    if ma_xa is None:
        return province['tenTinh'] if province else str(ma_tinh)

    commune = _cache['commune_features'].get(str(ma_xa), {}).get('properties', {})
    return commune.get('tenXa', str(ma_xa))
