from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
import os
from urllib.request import Request, urlopen
from urllib.parse import urlsplit, parse_qs, unquote
import json, io, zipfile

TARGET = 'https://api.tokengo.love'
API_KEY = os.environ.get('TOKEN_GO_API_KEY', '').strip()

class Handler(SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path.startswith('/proxy/'):
            self.forward('GET')
        else:
            super().do_GET()

    def do_POST(self):
        if self.path.startswith('/proxy/'):
            self.forward('POST')
        elif self.path == '/batch-zip':
            self.batch_zip()
        else:
            self.send_error(404)

    def do_OPTIONS(self):
        if self.path.startswith('/proxy/'):
            self.send_response(204); self.send_header('Access-Control-Allow-Origin','*'); self.send_header('Access-Control-Allow-Headers','*'); self.send_header('Access-Control-Allow-Methods','GET,POST,OPTIONS'); self.end_headers()
        else:
            self.send_error(404)

    def do_GET(self):
        if self.path.startswith('/asset?'):
            url = parse_qs(urlsplit(self.path).query).get('url', [''])[0]
            try:
                res = urlopen(url, timeout=120); body = res.read()
                # Detect the actual file signature; upstream MIME can be wrong.
                if body.startswith(b'\xff\xd8\xff'): ctype = 'image/jpeg'
                elif body.startswith(b'\x89PNG\r\n\x1a\n'): ctype = 'image/png'
                elif body[:4] == b'RIFF' and body[8:12] == b'WEBP': ctype = 'image/webp'
                else: ctype = res.headers.get('Content-Type','image/jpeg').split(';')[0]
                ext = '.png' if ctype == 'image/png' else ('.webp' if ctype == 'image/webp' else '.jpg')
                self.send_response(200); self.send_header('Content-Type', ctype); self.send_header('Content-Disposition', 'attachment; filename="image'+ext+'"'); self.send_header('Content-Length', str(len(body))); self.end_headers(); self.wfile.write(body)
            except Exception as e: self.send_error(502, str(e))
        elif self.path.startswith('/proxy/'):
            self.forward('GET')
        else: super().do_GET()

    def batch_zip(self):
        length = int(self.headers.get('Content-Length', '0')); payload = json.loads(self.rfile.read(length) or '{}')
        out = io.BytesIO()
        with zipfile.ZipFile(out, 'w', zipfile.ZIP_DEFLATED) as z:
            for item in payload.get('files', []):
                try: z.writestr(item.get('name','image.jpg'), urlopen(item['url'], timeout=120).read())
                except Exception: pass
        body = out.getvalue(); self.send_response(200); self.send_header('Content-Type','application/zip'); self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)

    def forward(self, method):
        target = TARGET + self.path[len('/proxy'):]
        length = int(self.headers.get('Content-Length', '0'))
        data = self.rfile.read(length) if length else None
        headers = {k: v for k, v in self.headers.items() if k.lower() not in ('host', 'content-length')}
        if API_KEY and not any(k.lower() == 'authorization' for k in headers):
            headers['Authorization'] = 'Bearer ' + API_KEY
        try:
            res = urlopen(Request(target, data=data, headers=headers, method=method), timeout=180)
            body = res.read()
            self.send_response(res.status)
            for k, v in res.headers.items():
                if k.lower() not in ('transfer-encoding', 'connection'):
                    self.send_header(k, v)
            self.end_headers(); self.wfile.write(body)
        except Exception as e:
            self.send_error(502, str(e))

if __name__ == '__main__':
    port = int(os.environ.get('PORT', '8765'))
    host = os.environ.get('HOST', '127.0.0.1')
    print(f'打开 http://{host}:{port}/ai-image-studio.html')
    ThreadingHTTPServer((host, port), Handler).serve_forever()
