"""
EntryFlow Tally Prime Port 9000 Live Bridge
Zero-dependency desktop companion for instant, 0-click voucher injection into Tally Prime.

Requirements:
- Windows PC with Tally Prime open
- Enable Port 9000 in Tally Prime:
  Press F1 (Help) > Settings > Connectivity > Client/Server configuration > TallyPrime acts as: Both, Port: 9000.

Usage:
  python tally_bridge.py --api-key YOUR_ENTRYFLOW_KEY
"""

import sys
import time
import argparse
import urllib.request
import urllib.parse
import json

TALLY_URL = "http://localhost:9000"
DEFAULT_API_BASE = "https://entryflow.co.in"

def check_tally_connection():
    print(f"[*] Checking connection to Tally Prime on {TALLY_URL}...")
    req_xml = """<ENVELOPE>
      <HEADER><TALLYREQUEST>Export Data</TALLYREQUEST></HEADER>
      <BODY>
        <EXPORTDATA>
          <REQUESTDESC>
            <REPORTNAME>List of Companies</REPORTNAME>
            <STATICVARIABLES><SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT></STATICVARIABLES>
          </REQUESTDESC>
        </EXPORTDATA>
      </BODY>
    </ENVELOPE>"""
    try:
        req = urllib.request.Request(
            TALLY_URL,
            data=req_xml.encode("utf-8"),
            headers={"Content-Type": "text/xml"}
        )
        with urllib.request.urlopen(req, timeout=3) as resp:
            data = resp.read().decode("utf-8", errors="ignore")
            if "<RESPONSE>" in data or "<BODY>" in data or "<COMPANYNAME>" in data:
                print("[+] SUCCESS: Connected to Tally Prime on Port 9000!")
                return True
    except Exception as e:
        print(f"[-] Could not connect to Tally Prime: {e}")
        print("[-] Please ensure Tally Prime is running and Port 9000 is enabled in F1 > Settings > Connectivity.")
        return False

def inject_xml_to_tally(xml_content: str) -> bool:
    try:
        req = urllib.request.Request(
            TALLY_URL,
            data=xml_content.encode("utf-8"),
            headers={"Content-Type": "text/xml"}
        )
        with urllib.request.urlopen(req, timeout=10) as resp:
            resp_data = resp.read().decode("utf-8", errors="ignore")
            if "<CREATED>1</CREATED>" in resp_data or "<ALTERED>1</ALTERED>" in resp_data:
                print("[+] VOUCHER INJECTED SUCCESSFULLY INTO TALLY PRIME!")
                return True
            elif "<ERRORS>0</ERRORS>" in resp_data:
                print("[+] VOUCHER POSTED CLEANLY (0 Errors)!")
                return True
            else:
                print(f"[-] Tally Response: {resp_data[:300]}")
                return False
    except Exception as e:
        print(f"[-] Error injecting to Tally: {e}")
        return False

def watch_entryflow(api_key: str, server_url: str):
    print(f"[*] Listening for incoming vouchers from EntryFlow ({server_url})...")
    print("[*] Press Ctrl+C to stop.")
    last_processed = set()
    
    while True:
        try:
            url = f"{server_url}/v1/dashboard/data"
            req = urllib.request.Request(url, headers={"User-Agent": "EntryFlow-Bridge/1.0"})
            with urllib.request.urlopen(req, timeout=8) as resp:
                data = json.loads(resp.read().decode("utf-8"))
                invoices = data.get("invoices", [])
                for inv in invoices:
                    inv_id = inv.get("id")
                    if inv_id and inv_id not in last_processed:
                        xml_str = inv.get("xml")
                        if xml_str and "<ENVELOPE>" in xml_str:
                            print(f"[>] Found new bill {inv.get('invNo')} from {inv.get('supplier')} (Total: Rs. {inv.get('total')})")
                            success = inject_xml_to_tally(xml_str)
                            if success:
                                last_processed.add(inv_id)
        except Exception as err:
            pass
        time.sleep(3)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="EntryFlow Tally Prime Port 9000 Direct Injector")
    parser.add_argument("--api-key", default="ef_live_demo", help="Your EntryFlow API Key")
    parser.add_argument("--server", default=DEFAULT_API_BASE, help="EntryFlow server URL")
    args = parser.parse_args()
    
    print("=" * 60)
    print(" EntryFlow Tally Prime Port 9000 Direct Bridge v1.0")
    print("=" * 60)
    
    if check_tally_connection():
        watch_entryflow(args.api_key, args.server)
    else:
        sys.exit(1)
