"""Explicit, fixed-value file adapter; not a Foggy native import interface."""
from pathlib import Path
from decimal import Decimal
from datetime import datetime
import argparse,csv,json,sqlite3,hashlib

HEADERS=['账单编号','客户编号','账单日期','账单国家','账单金额']
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def read_records(path):
    if path.suffix.lower()=='.xlsx':
        import openpyxl
        wb=openpyxl.load_workbook(path,read_only=True,data_only=False)
        assert wb.sheetnames==['账单'],'Select the documented sheet explicitly'
        ws=wb['账单']
        values=list(ws.iter_rows(min_col=1,max_col=5,values_only=False))
        assert [c.value for c in values[0]]==HEADERS,'Header contract changed'
        assert not any(c.data_type=='f' for row in values[1:] for c in row),'Fixed-value fixture only; formulas require a separate import contract'
        rows=[[c.value for c in row] for row in values[1:]]
        wb.close()
    elif path.suffix.lower()=='.csv':
        with path.open(encoding='utf-8-sig',newline='') as src:
            reader=csv.reader(src);assert next(reader)==HEADERS;rows=list(reader)
    else:raise ValueError('Only the tested .xlsx or UTF-8 CSV fixture is supported')
    out=[];seen=set()
    for source_row,row in enumerate(rows,start=2):
        assert len(row)==5 and all(v is not None and v!='' for v in row),(source_row,'missing required value')
        iid,code,date,country,amount=row
        assert isinstance(iid,str) and isinstance(code,str),(source_row,'identifiers must be text')
        assert len(code)==5 and code.isdigit(),(source_row,'expected five-digit teaching code')
        assert iid not in seen,(source_row,'duplicate invoice ID',iid)
        seen.add(iid)
        if isinstance(date,datetime):date=date.strftime('%Y-%m-%d %H:%M:%S')
        else:datetime.strptime(date,'%Y-%m-%d %H:%M:%S')
        value=Decimal(str(amount))
        assert value.is_finite() and value==value.quantize(Decimal('.01')),(source_row,'amount precision changed')
        out.append((iid,code,date,str(country),str(value),source_row))
    return out

def main():
    parser=argparse.ArgumentParser();parser.add_argument('--source',type=Path,required=True);parser.add_argument('--database',type=Path,required=True);args=parser.parse_args()
    records=read_records(args.source);digest=sha(args.source)
    args.database.parent.mkdir(parents=True,exist_ok=True)
    with sqlite3.connect(args.database) as db:
        db.execute('create table if not exists file_invoices(invoice_id TEXT PRIMARY KEY, customer_code TEXT NOT NULL, invoice_date DATETIME NOT NULL, billing_country TEXT NOT NULL, invoice_amount DECIMAL(18,2) NOT NULL, source_row INTEGER NOT NULL)')
        # A complete file snapshot replaces this adapter-owned table, not an append.
        db.execute('delete from file_invoices')
        db.executemany('insert into file_invoices values(?,?,?,?,?,?)',records)
        db.execute('create table if not exists file_import(source_name TEXT PRIMARY KEY, source_sha256 TEXT NOT NULL, row_count INTEGER NOT NULL)')
        db.execute('delete from file_import');db.execute('insert into file_import values(?,?,?)',(args.source.name,digest,len(records)))
    report={'source':str(args.source.resolve()),'sourceSha256':digest,'database':str(args.database.resolve()),'rows':len(records),'customers':len({r[1] for r in records}),'amount':str(sum((Decimal(r[4]) for r in records),Decimal(0))),'rule':'replace complete snapshot of adapter-owned table; fixed values only','sourceWorkbookUnchanged':sha(args.source)==digest}
    args.database.with_suffix('.import.json').write_text(json.dumps(report,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
    print(json.dumps(report,ensure_ascii=True))
if __name__=='__main__':main()
