from typing import Optional,List
from lib.porxy import PlatformProxy
from db.database import mysqlClient
from log import log

logger = log(__name__)

class Reconciliation:
    def __init__(self, service_id: str, type: int,
                 start_date: Optional[str] = None,
                 start_hour: Optional[int] = None) -> None:
        self.service_id = service_id
        self.type = type
        self.start_date = start_date
        self.start_hour = start_hour

    async def run(self,local_data:List[dict]) -> int:
        # Step 1: 构造查询参数
        query_params = {"serviceId": self.service_id}
        query_params["date"] = self.start_date
        query_params["hour"] = self.start_hour

        # Step 2: 发送查询请求
        api_url = "/api/v1/park/order/controller/confirm/query/"
        http_proxy = PlatformProxy()
        try:
            resp = await http_proxy.post(api_url, query_params, timeOut=15)
        except Exception as e:
            logger.error(f"Failed to query bill: {e}")
            return -1
        logger.info(f"resp_len:{len(resp['qs'])}")
        # Step 3: 对比差异并推送
        diff = self.compare_with_local_data(local_data,resp.get("qs",[]))
        if diff:
            push_result = await self.push_diff(diff)
            if push_result != 0:
                return -1

        return 0
    
    async def query_local_data(self):
        sql = '''
        SELECT bk.payNo AS payNo,
            bk.insertDate AS insertDate,
            bk.insertHour AS insertHour,
            bk.devNumber AS devNumber
        FROM book_keep.book_keep AS bk
        LEFT JOIN book_keep.trade_revoke tr
            ON bk.payNo = tr.payNo
        LEFT JOIN book_keep.callback_res cr
            ON bk.payNo = cr.pay_no
        WHERE bk.insertDate = %s
            AND bk.isUpload IN %s
            AND bk.isDelete = %s
            AND bk.serviceId = %s
            AND cr.callback_status = %s
            AND tr.revokeTime is null
        '''
        params = (self.start_date,(0,1),0,self.service_id,1)
        cur = await mysqlClient.execute(sql,params)
        local_data = await cur.fetchall()
        return local_data


    def compare_with_local_data(self,local:List[dict], resp: List[dict]) -> dict:
        # TODO: 实现与本地数据对比的逻辑
        local_orders = [order['payNo'] for order in local]
        resp_orders = [order['payNo'] for order in resp]
        lack = list(set(local_orders) - set(resp_orders)) #短款
        overstep = list(set(resp_orders) - set(local_orders)) #长款
        #暂无金额数据满足对账格式即可
        return {
            "overstep":[{"fee":0,"payNo":order_id} for order_id  in overstep],
            "lack":[{"fee":0,"payNo":order_id} for order_id in lack]
        }

    async def push_diff(self, diff: dict) -> int:
        # TODO: 实现推送差异的逻辑
        api_url = "/api/v1/park/order/controller/confirm/callback/save/"
        http_proxy = PlatformProxy()
        push_params = {
            "date":self.start_date,
            "hour":self.start_hour,
            "overstep":diff["overstep"],
            "lack":diff["lack"],
            "serviceId":self.service_id,
            "tag":2,
            'role':1,
        }
        try:
            await http_proxy.post(api_url, push_params, timeOut=3)
        except Exception as e:
            logger.error(f"Failed to push bill: {e}")
            return -1
        return 0