from __future__ import annotations
import json, mimetypes, os, sys, traceback, webbrowser
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from pathlib import Path
from urllib.parse import urlparse
HERE = Path(__file__).resolve().parent
if str(HERE) not in sys.path:
    sys.path.insert(0, str(HERE))
try:
    from .research_engine import ResearchEngine
except ImportError:
    from research_engine import ResearchEngine

ROOT=Path(__file__).resolve().parents[1]
WEB=ROOT/'workbench'
ENGINE=ResearchEngine(ROOT)
HOST='127.0.0.1'; PORT=int(os.environ.get('CRD_PORT','8765'))

class Handler(BaseHTTPRequestHandler):
    server_version='CRDResearchWorkbench/0.6'
    def log_message(self,fmt,*args): print('[CRD]',fmt%args)
    def _json(self,status,data):
        body=json.dumps(data,ensure_ascii=False).encode('utf-8')
        self.send_response(status); self.send_header('Content-Type','application/json; charset=utf-8'); self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)
    def _read_json(self):
        n=int(self.headers.get('Content-Length','0')); return json.loads(self.rfile.read(n).decode('utf-8')) if n else {}
    def do_GET(self):
        p=urlparse(self.path).path
        if p=='/api/health': return self._json(200,{"ok":True,"service":"CRD Sprint 6 Research Engine","version":"0.6.0"})
        rel='index.html' if p in ('/','') else p.lstrip('/')
        target=(WEB/rel).resolve()
        if not str(target).startswith(str(WEB.resolve())) or not target.exists() or not target.is_file(): self.send_error(404); return
        data=target.read_bytes(); ctype=mimetypes.guess_type(target.name)[0] or 'application/octet-stream'
        self.send_response(200); self.send_header('Content-Type',ctype); self.send_header('Content-Length',str(len(data))); self.end_headers(); self.wfile.write(data)
    def do_POST(self):
        p=urlparse(self.path).path
        try:
            payload=self._read_json()
            if p=='/api/research':
                medication=str(payload.get('medication','')).strip()
                if not medication: return self._json(400,{"error":"Medication is required."})
                return self._json(200,ENGINE.run(medication,payload.get('connectors')))
            if p=='/api/fetch-url':
                url=str(payload.get('url','')).strip()
                if not url.startswith(('https://','http://')): return self._json(400,{"error":"A valid http(s) URL is required."})
                return self._json(200,ENGINE.fetch_url(url))
            if p=='/api/upload':
                return self._json(200,ENGINE.parse_upload(str(payload.get('filename','upload')),str(payload.get('dataBase64',''))))
            return self._json(404,{"error":"Unknown endpoint"})
        except Exception as exc:
            traceback.print_exc(); return self._json(500,{"error":str(exc),"type":type(exc).__name__})

def main():
    httpd=ThreadingHTTPServer((HOST,PORT),Handler)
    url=f'http://{HOST}:{PORT}/'
    print(f'Clinical Reasoning Database Sprint 6 running at {url}')
    if '--no-browser' not in sys.argv: webbrowser.open(url)
    try: httpd.serve_forever()
    except KeyboardInterrupt: pass
    finally: httpd.server_close()
if __name__=='__main__': main()
