#!/usr/bin/env python3
"""Mock of the BarKala /api (فقط برای تست فرانت‌اند؛ جایگزین بک‌اند واقعی نیست).
اجرا:  python3 tests/mock_api.py   (پورت 8777؛ فایل‌های frontend را هم سرو می‌کند)"""
import json, http.server, socketserver, os, sys, time
ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'frontend')
os.chdir(ROOT)
NOAPI = '--noapi' in sys.argv
PORT = int(sys.argv[1]) if len(sys.argv) > 1 and sys.argv[1].isdigit() else 8777
USERS = {'admin@x': ('good', 'u1'), 'viewer@x': ('good', 'u2')}
ROLES = {'u1': 'admin', 'u2': 'retail'}
def fresh():
    return {'user': None, 'settings': {}, 'log': [],
            'rows': [{"id": "r%d" % i, "invoice_group_id": "g%d" % (i // 2), "invoice_no": "1405071%d-00%d-K7X" % (i // 2, i // 2), "invoice_page": 1, "invoice_pages": 1,
                      "sender_role": "marketer", "sender_token": "mkT", "sender_name": "علی", "image_data": "data:image/png;base64,iVBORw0KGgo=",
                      "invoice_data": {"invoiceNo": "1405071%d-00%d-K7X" % (i // 2, i // 2), "customer": {"name": "مشتری %d" % i}, "items": [], "grandTotal": 1000 * i},
                      "created_ts": 1760000000000 + i * 1000, "status": "pending", "status_updated_at": None, "printed_at": None} for i in range(1, 701)]}
S = fresh()
class H(http.server.SimpleHTTPRequestHandler):
    def log_message(self, *a): pass
    def j(self, obj, code=200):
        b = json.dumps(obj).encode(); self.send_response(code); self.send_header('Content-Type', 'application/json'); self.send_header('Content-Length', str(len(b))); self.end_headers(); self.wfile.write(b)
    def admin(self): return S['user'] and ROLES.get(S['user']['id']) == 'admin'
    def do_POST(self):
        if NOAPI: return self.send_error(404)
        n = int(self.headers.get('Content-Length') or 0); d = json.loads(self.rfile.read(n) or b'{}'); p = self.path
        if p == '/api/query':
            t = d.get('table'); S['log'].append(['query', t, d.get('select'), d.get('limit')])
            if t == 'bk_invoice_messages':
                if not self.admin(): return self.j({"error": {"message": "FORBIDDEN"}}, 403)
                rows = S['rows'][:]
                for f in d.get('filters', []):
                    if f['op'] == 'gt': rows = [r for r in rows if r[f['col']] > f['value']]
                o = d.get('orders', [])
                if o: rows.sort(key=lambda r: r[o[0]['col']], reverse=not o[0]['ascending'])
                rows = rows[:d.get('limit') or 1000]
                sel = d.get('select', '*')
                if sel != '*': rows = [{c: r[c] for c in sel.split(',')} for r in rows]
                return self.j({"data": rows})
            if t == 'profiles':
                uid = next((f['value'] for f in d.get('filters', []) if f['col'] == 'id'), None)
                return self.j({"data": {"role": ROLES.get(uid, 'retail')}})
            if t == 'bk_settings': return self.j({"data": [{"key": k, "value": v[0], "updated_at": v[1]} for k, v in S['settings'].items()]})
            return self.j({"data": []})
        if p == '/api/mutate':
            t = d.get('table'); S['log'].append(['mutate', t, d.get('op')])
            if not self.admin(): return self.j({"error": {"message": "FORBIDDEN"}}, 403)
            if t == 'bk_settings' and d.get('op') == 'upsert':
                for r in d['rows']: S['settings'][r['key']] = (r['value'], r['updated_at'])
                return self.j({"data": [r['key'] for r in d['rows']]})
            if t == 'bk_invoice_messages' and d.get('op') == 'delete':
                S['rows'] = [r for r in S['rows'] if r['id'] != d.get('id')]; return self.j({"data": [d.get('id')]})
            return self.j({"data": []})
        if p == '/api/auth/signin':
            u = USERS.get(d.get('email'))
            if u and u[0] == d.get('password'): S['user'] = {'id': u[1], 'email': d['email']}; return self.j({"data": {"user": S['user']}})
            return self.j({"error": {"message": "رمز نادرست"}}, 401)
        if p == '/api/auth/session': return self.j({"data": {"user": S['user']} if S['user'] else None})
        if p == '/api/auth/signout': S['user'] = None; return self.j({"data": True})
        return self.j({"data": None})
    def do_GET(self):
        if self.path.startswith('/api/health') and not NOAPI: return self.j({"data": {"ok": True}})
        if self.path == '/_log': return self.j(S['log'])
        if self.path == '/_reset':
            S.clear(); S.update(fresh()); return self.j({"ok": True})
        if self.path == '/_settings': return self.j(S['settings'])
        super().do_GET()
socketserver.TCPServer.allow_reuse_address = True
if __name__ == '__main__':
    socketserver.ThreadingTCPServer(('', PORT), H).serve_forever()
