#!/usr/bin/env python3
"""WeChat webhook receiver v2 - receives messages from docker-wechatbot-webhook."""

import os, sys, json, logging, threading
from http.server import HTTPServer, BaseHTTPRequestHandler

HERMES_API = "http://192.168.1.246:8642/v1/chat/completions"
HERMES_KEY = "hermes123"
PORT = 5804

WECHAT_BOT_TOKEN = os.environ.get("WECHAT_BOT_TOKEN", "mowechat_fixed_token_001")

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler("/home/hmo/projects/AgentsMeeting/gateway/linux/logs/webhook.log"),
        logging.StreamHandler()
    ]
)
log = logging.getLogger("wc-webhook")


class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_type = self.headers.get('Content-Type', '')
        content_length = int(self.headers.get('Content-Length', 0))
        
        # Read the body
        body = self.rfile.read(content_length)
        
        # Parse multipart/form-data
        msg_type = 'unknown'
        content = ''
        source_raw = '{}'
        is_system = '0'
        
        if 'multipart/form-data' in content_type:
            # Manual multipart parsing
            boundary = content_type.split('boundary=')[1].strip()
            if boundary.startswith('"') and boundary.endswith('"'):
                boundary = boundary[1:-1]
            
            parts = body.split(b'--' + boundary.encode())
            for part in parts:
                if b'Content-Disposition' not in part:
                    continue
                
                # Parse headers
                header_end = part.find(b'\r\n\r\n')
                if header_end < 0:
                    continue
                part_headers = part[:header_end].decode('utf-8', errors='replace')
                part_body = part[header_end + 4:]
                
                # Get field name
                name_start = part_headers.find('name="')
                if name_start < 0:
                    continue
                name_start += 6
                name_end = part_headers.find('"', name_start)
                field_name = part_headers[name_start:name_end]
                
                # Trim trailing \r\n--
                if part_body.endswith(b'\r\n'):
                    part_body = part_body[:-2]
                if part_body.endswith(b'--'):
                    part_body = part_body[:-2]
                if part_body.endswith(b'\r\n'):
                    part_body = part_body[:-2]
                
                if field_name == 'type':
                    msg_type = part_body.decode('utf-8', errors='replace')
                elif field_name == 'content':
                    content = part_body.decode('utf-8', errors='replace')
                elif field_name == 'source':
                    source_raw = part_body.decode('utf-8', errors='replace')
                elif field_name == 'isSystemEvent':
                    is_system = part_body.decode('utf-8', errors='replace')
        else:
            # Try as regular form or JSON
            try:
                data = json.loads(body)
                msg_type = data.get('type', 'unknown')
                content = data.get('content', '')
                source_raw = data.get('source', '{}')
            except:
                pass
        
        # Parse source
        try:
            source = json.loads(source_raw) if isinstance(source_raw, str) else source_raw
        except:
            source = {}
        
        # Extract sender info
        sender_name = "unknown"
        sender_id = "unknown"
        if isinstance(source, dict):
            from_data = source.get('from', {})
            if isinstance(from_data, dict):
                payload = from_data.get('payload', {})
                sender_name = payload.get('name', 'unknown')
                sender_id = payload.get('id', 'unknown')
        
        # Skip system events
        if is_system == '1':
            log.info(f"System event: {msg_type}")
            self._respond(200, {"status": "ok"})
            return
        
        log.info(f"From: {sender_name} ({sender_id}), Type: {msg_type}")
        
        if msg_type == 'text':
            log.info(f"Text: {content[:300]}")
            self._forward_to_hermes(sender_name, sender_id, content)
        elif msg_type == 'urlLink':
            log.info(f"URL: {content[:200]}")
            self._forward_to_hermes(sender_name, sender_id, f"[分享链接] {content}")
        elif msg_type == 'file':
            log.info(f"File received, length={len(body)}")
        else:
            log.info(f"Other: {msg_type}")
        
        self._respond(200, {"status": "ok"})
    
    def _forward_to_hermes(self, sender, sender_id, text):
        """Forward message to Hermes, get response, send back to WeChat."""
        payload = json.dumps({
            "model": "nova-4",
            "messages": [
                {"role": "user", "content": f"[微信消息] 来自 {sender}({sender_id}): {text}"}
            ]
        }).encode()
        
        def do_forward():
            try:
                import urllib.request as ureq
                handler = ureq.ProxyHandler({})
                opener = ureq.build_opener(handler)
                req = ureq.Request(HERMES_API, data=payload,
                    headers={"Content-Type": "application/json", "Authorization": f"Bearer {HERMES_KEY}"})
                resp = opener.open(req, timeout=180)
                resp_data = json.loads(resp.read())
                reply = resp_data.get('choices', [{}])[0].get('message', {}).get('content', '')
                log.info(f"Hermes OK, reply: {reply[:60]}")
                
                if reply and sender:
                    self._send_wechat(sender, reply)
            except Exception as e:
                log.error(f"Hermes error: {e}")
        
        threading.Thread(target=do_forward, daemon=True).start()
    
    def _send_wechat(self, to_name, text):
        """Send message back to WeChat user via bot API."""
        import urllib.request as ureq
        token = WECHAT_BOT_TOKEN
        api = f"http://localhost:3001/webhook/msg/v2?token={token}"
        data = json.dumps({"to": to_name, "data": {"content": text}}).encode()
        try:
            handler = ureq.ProxyHandler({})
            opener = ureq.build_opener(handler)
            req = ureq.Request(api, data=data,
                headers={"Content-Type": "application/json"})
            resp = opener.open(req, timeout=10)
            log.info(f"WeChat send OK: {resp.status}")
        except Exception as e:
            log.error(f"WeChat send error: {e}")
    
    def _respond(self, code, data):
        self.send_response(code)
        self.send_header('Content-Type', 'application/json')
        self.end_headers()
        self.wfile.write(json.dumps(data).encode())
    
    def log_message(self, format, *args):
        pass


def main():
    server = HTTPServer(('0.0.0.0', PORT), WebhookHandler)
    log.info(f"Webhook receiver on :{PORT}")
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()


if __name__ == "__main__":
    main()
