"""
差旅报销填报流程

负责差旅报销的完整填报步骤：
    基本信息 → 差旅明细 → 支付方式 → 补助清单 → 附件上传
"""

from typing import Any

from .. import get_logger
from .base import BaseBot, format_date

log = get_logger("bot.travel")


# ------------------------------------------------------------------
# 差旅填报流程
# ------------------------------------------------------------------


def run(bot: BaseBot, travel_info: dict[str, Any]) -> None:
    """执行差旅报销填报流程

    Args:
        bot: 已启动并登录的 BaseBot 实例。
        travel_info: 差旅信息字典（包含 basic_info、reimbursement_details 等）。
    """
    log.info("开始差旅报销填报...")

    log.info("填写差旅报销信息...")
    basic_info = travel_info["basic_info"]
    fill_travel_info(bot, basic_info)

    log.info("填写差旅报销明细...")
    travel_items = travel_info["reimbursement_details"]
    add_travel_items(bot, travel_items)

    log.info("填写差旅报销支付方式...")
    payment_info = travel_info["payment_methods"]
    fill_travel_payment(bot, payment_info)

    log.info("填写差旅报销补助清单...")
    subsidy_info = travel_info["subsidy_list"]
    fill_travel_subsidy(bot, subsidy_info)

    log.info("上传差旅报销附件...")
    attachment_info = travel_info["attachments"]
    upload_travel_attachments(bot, attachment_info)

    log.info("差旅报销填报完成")


# ------------------------------------------------------------------
# 基本信息
# ------------------------------------------------------------------


def fill_travel_info(bot: BaseBot, basic_info: dict[str, Any]) -> None:
    """填写差旅报销基本信息"""
    try:
        bot.page.fill("#CAUSE", basic_info.get("travel_purpose", ""))
        bot.page.fill("#SITE", basic_info.get("travel_location", ""))

        bot.page.click("#PROJECTCODE", timeout=10000)
        bot.page.wait_for_timeout(1000)
        bot.page.wait_for_selector("#promodal .fixed-table-body tbody tr", timeout=10000)
        first_row = bot.page.query_selector("#promodal .fixed-table-body tbody tr")
        if first_row:
            first_row.click()
            bot.page.wait_for_timeout(1000)

        bot.page.fill("#THEKSRQ", format_date(basic_info.get("start_date", "")))
        bot.page.fill("#THEJSRQ", format_date(basic_info.get("end_date", "")))
        bot.page.click("#saveAndNext", timeout=5000)
        bot.page.wait_for_timeout(2000)
        bot._screenshot("travel_basic_done")
    except Exception:
        log.error("填写基本信息失败")
        bot._screenshot("travel_basic_error")


# ------------------------------------------------------------------
# 差旅明细
# ------------------------------------------------------------------


def add_travel_items(bot: BaseBot, travel_items: dict[str, Any]) -> None:
    """录入差旅报销明细"""
    vehicle_map = {
        "火车": "01",
        "汽车": "02",
        "轮船": "03",
        "自带车": "04",
        "公务车": "05",
        "飞机": "06",
        "租车": "07",
        "自驾车": "08",
    }

    try:
        traffic_info = travel_items.get("transport_fee") or []
        for item in traffic_info:
            bot.page.click("#insertDetail", timeout=5000)
            bot._wait_for('text="增加明细"', timeout=5000)
            bot.page.select_option("#cost", "1")
            bot.page.wait_for_timeout(500)
            vehicle = item.get("vehicle_type", "")
            if vehicle in vehicle_map:
                bot.page.select_option("#jtgj", vehicle_map[vehicle])

            bot.page.fill("#ksdd", item.get("departure_place", ""))
            bot.page.fill("#jsdd", item.get("arrival_place", ""))
            bot.page.fill(
                '#t1 input[name="expenPwTraveldetail.MONEY"]',
                str(item.get("amount", "")),
            )
            bot.page.fill(
                '#t1 input[name="expenPwTraveldetail.HOWBILL"]',
                str(item.get("bill_count", "")),
            )
            bot.page.fill(
                '#t1 input[name="expenPwTraveldetail.SMARK"]',
                str(item.get("remark", "")),
            )
            bot.page.click("#detailAdd", timeout=3000)
            bot.page.wait_for_timeout(1000)

        hotel_info = travel_items.get("hotel_fee") or []
        for item in hotel_info:
            bot.page.click("#insertDetail", timeout=5000)
            bot._wait_for('text="增加明细"', timeout=5000)
            bot.page.select_option("#cost", "2")
            bot.page.wait_for_timeout(500)
            bot.page.fill("#ksrq2", format_date(str(item.get("checkin_date", ""))))
            bot.page.fill("#jsrq2", format_date(str(item.get("checkout_date", ""))))
            bot.page.fill("#ts2", str(item.get("days", "")))
            bot.page.fill("#rs2", str(item.get("person_count", "")))
            bot.page.fill(
                '#t2 input[name="expenPwTraveldetail.FPMONEY"]',
                str(item.get("invoice_amount", "")),
            )
            bot.page.fill(
                '#t2 input[name="expenPwTraveldetail.MONEY"]',
                str(item.get("reimburse_amount", "")),
            )
            bot.page.fill(
                '#t2 input[name="expenPwTraveldetail.SMARK"]',
                str(item.get("remark", "")),
            )
            bot.page.click("#detailAdd", timeout=3000)
            bot.page.wait_for_timeout(1000)

        conference_info = travel_items.get("conference_fee") or []
        for item in conference_info:
            bot.page.click("#insertDetail", timeout=5000)
            bot._wait_for('text="增加明细"', timeout=5000)
            bot.page.select_option("#cost", "3")
            bot.page.wait_for_timeout(500)
            bot.page.fill(
                '#t3 input[name="expenPwTraveldetail.HOWBILL"]',
                str(item.get("bill_count", "")),
            )
            bot.page.fill(
                '#t3 input[name="expenPwTraveldetail.MONEY"]',
                str(item.get("amount", "")),
            )
            bot.page.fill(
                '#t3 input[name="expenPwTraveldetail.SMARK"]',
                str(item.get("remark", "")),
            )
            bot.page.click("#detailAdd", timeout=3000)
            bot.page.wait_for_timeout(1000)
    except Exception as e:
        log.error(f"录入总明细失败: {e}")
        bot._screenshot("item_total_error")
        raise


# ------------------------------------------------------------------
# 支付方式
# ------------------------------------------------------------------


def fill_travel_payment(bot: BaseBot, payment_info: list[dict[str, Any]]) -> None:
    """录入差旅支付信息"""
    try:
        bot.page.click('text="下一步(支付方式)"', timeout=5000)
        bot._wait_for('text="下一步(补助清单)"', timeout=5000)

        for info in payment_info:
            bot.page.click("#insertPay", timeout=5000)
            bot.page.wait_for_timeout(1000)
            bot.page.fill("#personid2", bot.config["default_name"])
            bot.page.fill("#accountname2", bot.config["default_person_id"])
            bot.page.fill("#receiptdate2", format_date(info["card_date"]))
            bot.page.fill("#localaccount2", bot.config["default_card_no"])
            bot.page.fill("#receiptmoney2", str(info["card_amount"]))
            bot.page.fill("#money2", str(info["card_amount"]))
            bot.page.fill("#merchant2", info.get("merchant", ""))
            bot.page.fill("#smark2", info.get("remark", ""))
            bot.page.click("#payAdd", timeout=3000)
            bot.page.wait_for_timeout(1000)
    except Exception as e:
        log.error(f"支付方式录入失败: {e}")
        bot._screenshot("step5_error")
        raise

    bot._screenshot("step5_done")


# ------------------------------------------------------------------
# 补助清单
# ------------------------------------------------------------------


def fill_travel_subsidy(bot: BaseBot, subsidy_info: list[dict[str, Any]]) -> None:
    """录入差旅补助清单"""
    try:
        bot.page.click("#next3", timeout=5000)
        bot._wait_for("#next4", timeout=5000)

        for info in subsidy_info:
            bot.page.click("#insertSubsidy", timeout=5000)
            bot._wait_for('text="增加补助清单"', timeout=5000)
            bot.page.click("#jzg3", timeout=5000)
            bot.page.wait_for_timeout(500)
            if info["person_name"] and info["person_name"] != "":
                bot.page.fill("#seacher", info["person_name"])
            elif info["person_id"] and info["person_id"] != "":
                bot.page.fill("#seacher", info["person_id"])
            else:
                raise ValueError(f"人员编号和人员姓名不能同时为空: {info}")
            bot.page.click("#cx", timeout=5000)
            bot.page.wait_for_selector("div.fixed-table-loading", state="hidden", timeout=10000)
            bot.page.click("#tableEmp tbody tr", timeout=10000)
            bot.page.wait_for_timeout(1000)

            open_bank = bot.page.input_value("#openbank1")
            if not open_bank:
                log.info("员工开户行未填写，默认填写中国工商银行")
                bot.page.fill("#openbank1", "中国工商银行")

            bot.page.fill("#startdate1", format_date(info["start_date"]))
            bot.page.fill("#enddate1", format_date(info["end_date"]))
            bot.page.fill("#trafficdays1", str(info["days"]))
            bot.page.fill("#fooddays1", str(info["days"]))
            bot.page.fill("#trafficnorm1", str(80))
            bot.page.fill("#foodnorm1", str(100))
            trafficmoney = int(info["days"]) * 80
            foodmoney = int(info["days"]) * 100
            subsidymoney = trafficmoney + foodmoney
            bot.page.fill("#trafficmoney1", str(trafficmoney))
            bot.page.fill("#foodmoney1", str(foodmoney))
            bot.page.fill("#subsidymoney1", str(subsidymoney))
            bot.page.click("#add", timeout=3000)
            bot.page.wait_for_timeout(1000)
    except Exception as e:
        log.error(f"差旅补助清单录入失败: {e}")
        bot._screenshot("subsidy_error")
        raise

    bot._screenshot("subsidy_done")


# ------------------------------------------------------------------
# 附件上传
# ------------------------------------------------------------------


def upload_travel_attachments(bot: BaseBot, attachment_info: list[dict[str, Any]]) -> None:
    """上传差旅附件"""
    try:
        bot.page.click("#next4", timeout=5000)
        bot._wait_for("#submit2", timeout=5000)

        for info in attachment_info:
            attachment_file = bot.work_dir / info["filename"]
            bot._wait_for("#insertAcc", timeout=20000)
            bot.page.click("#insertAcc", timeout=5000)
            bot._wait_for("#fjlx", timeout=5000)
            if info["attachment_type"] == "invoice":
                bot.page.select_option("#fjlx", "1")
            else:
                bot.page.select_option("#fjlx", "2")
            bot.page.fill("#fpsmxx", info["attachment_desc"])
            if attachment_file and attachment_file.exists():
                bot.page.set_input_files("#file", str(attachment_file))
                bot.page.wait_for_timeout(1000)
                bot.page.click("#cjtj", timeout=5000)
        log.info("上传差旅附件完成")
    except Exception as e:
        log.error(f"差旅附件上传失败: {e}")
        bot._screenshot("travel_attachment_error")
        raise
    bot._screenshot("travel_attachment_done")
