"""
extract/tally_reader.py — Pull existing data OUT of TallyPrime over HTTP (Port 9000).

TallyPrime exposes an XML gateway when ODBC / "acting as Both" is enabled.
We POST an <ENVELOPE> request and parse the XML response.
"""
import requests
import xml.etree.ElementTree as ET

from config import TALLY_URL, COMPANY_NAME


def _post(xml_request: str, timeout: int = 30) -> str:
    """POST a raw XML request to Tally and return the response text."""
    response = requests.post(
        TALLY_URL,
        data=xml_request.encode("utf-8"),
        headers={"Content-Type": "text/xml; charset=utf-8"},
        timeout=timeout,
    )
    response.raise_for_status()
    return response.text


def get_ledgers() -> list:
    """Pull all ledger names from TallyPrime."""
    xml_request = f"""
    <ENVELOPE>
      <HEADER><TALLYREQUEST>Export Data</TALLYREQUEST></HEADER>
      <BODY>
        <EXPORTDATA>
          <REQUESTDESC>
            <REPORTNAME>List of Ledgers</REPORTNAME>
            <STATICVARIABLES>
              <SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
              <SVCOMPANY>{COMPANY_NAME}</SVCOMPANY>
            </STATICVARIABLES>
          </REQUESTDESC>
        </EXPORTDATA>
      </BODY>
    </ENVELOPE>"""

    root = ET.fromstring(_post(xml_request))
    names = [el.text for el in root.iter("NAME") if el.text]
    return names


def get_vouchers(from_date: str, to_date: str) -> list:
    """
    Pull all vouchers in a date range.
    Dates format: YYYYMMDD  e.g. "20250101"
    """
    xml_request = f"""
    <ENVELOPE>
      <HEADER><TALLYREQUEST>Export Data</TALLYREQUEST></HEADER>
      <BODY>
        <EXPORTDATA>
          <REQUESTDESC>
            <REPORTNAME>Day Book</REPORTNAME>
            <STATICVARIABLES>
              <SVEXPORTFORMAT>$$SysName:XML</SVEXPORTFORMAT>
              <SVCOMPANY>{COMPANY_NAME}</SVCOMPANY>
              <SVFROMDATE>{from_date}</SVFROMDATE>
              <SVTODATE>{to_date}</SVTODATE>
            </STATICVARIABLES>
          </REQUESTDESC>
        </EXPORTDATA>
      </BODY>
    </ENVELOPE>"""

    root = ET.fromstring(_post(xml_request))
    vouchers = []

    for v in root.iter("VOUCHER"):
        vouchers.append({
            "date":      v.findtext("DATE", ""),
            "type":      v.findtext("VOUCHERTYPENAME", ""),
            "ref":       v.findtext("REFERENCE", ""),
            "amount":    v.findtext("AMOUNT", "0"),
            "narration": v.findtext("NARRATION", ""),
        })

    return vouchers


if __name__ == "__main__":
    # Quick self-test: python -m extract.tally_reader
    print("Ledgers in Tally:")
    for name in get_ledgers():
        print("  -", name)
