#!/usr/bin/env python3
"""Update map devices JSON every hour from three systems"""
import json, time, urllib.request, urllib.parse, subprocess, sys, os

KEY = "e274865463f2d4ca5676f076f86ac133"
GEO_URL = "https://restapi.amap.com/v3/geocode/geo"

def geocode(addr):
    if not addr or not addr.strip():
        return None
    params = urllib.parse.urlencode({'key': KEY, 'address': addr.strip()})
    url = f"{GEO_URL}?{params}"
    try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=10) as resp:
            data = json.loads(resp.read().decode())
            if data.get('status') == '1' and data.get('geocodes'):
                loc = data['geocodes'][0]['location']
                lng, lat = loc.split(',')
                return [float(lat), float(lng)]
    except:
        pass
    return None

def fetch_devices():
    results = {}

    # 海逸
    try:
        token = open('/tmp/haiyi_token.txt').read().strip()
        cmd = ['curl', '-s', '-o', '/tmp/haiyi_cabs.json',
               '-H', f'Authorization: Bearer {token}',
               'https://m.hykj.cn/locker-sub-merchant/api/sub/subweighingCabinet/getCabinetInfo']
        subprocess.run(cmd, timeout=30)
        with open('/tmp/haiyi_cabs.json') as f:
            devices = json.load(f)
        haiyi = []
        for item in devices:
            v = item.get('value', {})
            haiyi.append({
                'system': '海逸', 'name': v.get('deviceName') or v.get('containerAddress') or '未知',
                'address': v.get('detailedAddress', ''), 'readyNumber': item.get('label', '')
            })
        results['haiyi'] = haiyi
    except: pass

    # V2.0
    try:
        subprocess.run(['curl', '-s', '-c', '/tmp/v2_cookies_map.txt', '-X', 'POST',
            'https://new.baiguoyu888.tech/api/auth/admin/login',
            '-H', 'Content-Type: application/json', '-H', 'client-type: admin',
            '-d', '{"username":"13020181941","password":"888888"}'], timeout=15)
        subprocess.run(['curl', '-s', '-b', '/tmp/v2_cookies_map.txt',
            '-H', 'client-type: admin', '-o', '/tmp/v2_map.json',
            'https://new.baiguoyu888.tech/api/device'], timeout=30)
        with open('/tmp/v2_map.json') as f:
            resp = json.load(f)
        items = resp if isinstance(resp, list) else resp.get('data', [])
        v2 = []
        for d in items:
            addr = d.get('addressVO', {}) or {}
            v2.append({
                'system': 'V2.0', 'name': d.get('deviceName', ''),
                'address': addr.get('detailAddress', '') or addr.get('name', ''),
                'type': d.get('type', ''), 'state': d.get('state', ''),
                'temperature': d.get('temperature')
            })
        results['v2'] = v2
    except: pass

    # V1.0
    try:
        r = subprocess.run(['curl', '-s', '-X', 'POST',
            'https://www.baiguoyu888.tech/api/auth/login',
            '-H', 'Content-Type: application/json',
            '-d', '{"userName":"admin","password":"123456"}'],
            capture_output=True, text=True, timeout=15)
        v1_token = json.loads(r.stdout)['data']['token']
        subprocess.run(['curl', '-s', '-o', '/tmp/v1_map.json',
            '-H', f'token: {v1_token}',
            'https://www.baiguoyu888.tech/api/device'], timeout=30)
        with open('/tmp/v1_map.json') as f:
            resp = json.load(f)
        items = resp if isinstance(resp, list) else resp.get('data', [])
        v1 = []
        for d in items:
            v1.append({
                'system': 'V1.0', 'name': d.get('deviceName', ''),
                'address': d.get('detailAddress', '') or d.get('addressName', '')
            })
        results['v1'] = v1
    except: pass

    return results

# Load cache
try:
    with open('/tmp/geocode_cache.json') as f:
        cache = json.load(f)
except:
    cache = {}

# Fetch
data = fetch_devices()

new_geocode = 0
for sys_name, devices in data.items():
    for d in devices:
        addr = (d.get('address') or '').strip()
        addr = ' '.join(addr.split())
        if addr in cache:
            d['latlon'] = cache[addr]
        elif addr:
            loc = geocode(addr)
            d['latlon'] = loc
            cache[addr] = loc
            new_geocode += 1

# Save cache
with open('/tmp/geocode_cache.json', 'w') as f:
    json.dump(cache, f, ensure_ascii=False)

# Deduplicate and merge
from collections import defaultdict
loc_groups = defaultdict(list)
for sys_name, devices in data.items():
    for d in devices:
        if d.get('latlon'):
            key = f"{d['latlon'][0]:.5f},{d['latlon'][1]:.5f}"
            loc_groups[key].append(d)

merged = []
for key, group in loc_groups.items():
    if len(group) == 1:
        g = group[0]
        merged.append({
            'sys': {'haiyi':'海逸','v2':'V2.0','v1':'V1.0'}.get(g.get('system',''), g.get('system','')),
            'name': g.get('name',''), 'addr': g.get('address',''),
            'lat': g['latlon'][0], 'lng': g['latlon'][1],
            'temp': g.get('temperature'), 'state': g.get('state', g.get('cabinetOnlineStatus','')),
            'type': g.get('type','')
        })
    else:
        names = [g.get('name','') for g in group]
        temps = [g.get('temperature') for g in group if g.get('temperature') is not None]
        sys_tags = list(set({'haiyi':'海逸','v2':'V2.0','v1':'V1.0'}.get(g.get('system',''), g.get('system','')) for g in group))
        merged.append({
            'sys': '/'.join(sys_tags), 'name': '、'.join(names[:6]) + (f' 等{len(names)}台' if len(names)>6 else ''),
            'addr': group[0].get('address',''), 'lat': group[0]['latlon'][0], 'lng': group[0]['latlon'][1],
            'temp': round(sum(temps)/len(temps),1) if temps else None,
            'state': group[0].get('state', group[0].get('cabinetOnlineStatus','')),
            'type': group[0].get('type',''), 'count': len(group),
            'children': [{'name': g.get('name',''), 'sys': {'haiyi':'海逸','v2':'V2.0','v1':'V1.0'}.get(g.get('system',''), g.get('system','')),
                          'temp': g.get('temperature'), 'state': g.get('state', g.get('cabinetOnlineStatus',''))} for g in group]
        })

with open('/tmp/map_devices.json', 'w') as f:
    json.dump(merged, f, ensure_ascii=False)

# Rebuild HTML
from datetime import datetime
template = open('/tmp/baiguoyu_map_template.html').read()
html = template.replace('__DEVICES_JSON__', json.dumps(merged, ensure_ascii=False))
html = html.replace('__UPDATE_TIME__', datetime.now().strftime('%Y-%m-%d %H:%M'))
with open('/tmp/baiguoyu_map.html', 'w') as f:
    f.write(html)

total = sum(len(v) for v in data.values())
geo = sum(1 for d in merged)
print(f"OK: {total} devices, {geo} markers, {new_geocode} new geocoded")
