"""OrderMetadataExtractor 单元测试。"""
import unittest
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))

from app.core.ocr.metadata_extractor import (
    OrderMetadataExtractor, OrderMetadata, sanitize_for_filename,
)


class TestSupplierExtraction(unittest.TestCase):
    def setUp(self):
        self.ext = OrderMetadataExtractor()

    def test_keyword_supplier(self):
        text = "永辉超市供货单\n日期: 2026-07-17\n商品名称 条形码..."
        m = self.ext.extract(text)
        self.assertIn("永辉", m.supplier)
        self.assertIn("供货单", m.supplier)

    def test_supplier_keyword_no_data(self):
        text = "供应商: 益选烟酒商行\n日期: 2026-07-17"
        m = self.ext.extract(text)
        self.assertIn("益选", m.supplier)

    def test_fallback_supplier(self):
        text = "杭州朝阳酒业有限公司\n日期: 2026-07-17"
        m = self.ext.extract(text)
        self.assertIn("朝阳", m.supplier)

    def test_date_only_excluded(self):
        """纯日期行不该被当作供应商。"""
        text = "单据日期：2026-07-17\n成都瑞晨丰商贸销售出库单\n..."
        m = self.ext.extract(text)
        self.assertNotIn("日期", m.supplier)
        self.assertIn("瑞晨丰", m.supplier)

    def test_date_prefix_excluded(self):
        """以"日期"开头的行不该被当作供应商。"""
        text = "日期 2026-07-17\n永辉超市供货单\n..."
        m = self.ext.extract(text)
        self.assertNotIn("日期", m.supplier)
        self.assertIn("永辉", m.supplier)


class TestDateExtraction(unittest.TestCase):
    def setUp(self):
        self.ext = OrderMetadataExtractor()

    def test_dash_date(self):
        m = self.ext.extract("日期 2026-07-17 其他内容")
        self.assertEqual(m.bill_date, "20260717")

    def test_slash_date(self):
        m = self.ext.extract("日期 2026/07/17 其他内容")
        self.assertEqual(m.bill_date, "20260717")

    def test_dot_date(self):
        m = self.ext.extract("日期 2026.07.17 其他内容")
        self.assertEqual(m.bill_date, "20260717")

    def test_chinese_date(self):
        m = self.ext.extract("日期 2026年7月17日 其他内容")
        self.assertEqual(m.bill_date, "20260717")

    def test_compact_date(self):
        m = self.ext.extract("日期 20260717 其他内容")
        self.assertEqual(m.bill_date, "20260717")

    def test_invalid_date(self):
        m = self.ext.extract("日期 1800-01-01 其他内容")  # 年份越界
        self.assertEqual(m.bill_date, "")

    def test_no_date(self):
        m = self.ext.extract("没有任何日期")
        self.assertEqual(m.bill_date, "")


class TestAmountExtraction(unittest.TestCase):
    def setUp(self):
        self.ext = OrderMetadataExtractor()

    def test_payable_amount(self):
        text = "商品名称 条形码\n应付金额 656.00\n总计 12 件 656.00"
        m = self.ext.extract(text)
        self.assertEqual(m.total_amount, 656.00)

    def test_total_only(self):
        text = "总计 12 件 656.00"
        m = self.ext.extract(text)
        self.assertEqual(m.total_amount, 656.00)

    def test_max_amount_fallback(self):
        text = "55.00 62.00 57.00 33.50\n各种单价"
        m = self.ext.extract(text)
        self.assertEqual(m.total_amount, 62.00)

    def test_no_amount(self):
        text = "没有任何数字123"
        m = self.ext.extract(text)
        self.assertEqual(m.total_amount, 0.0)


class TestCombined(unittest.TestCase):
    def setUp(self):
        self.ext = OrderMetadataExtractor()

    def test_realistic(self):
        text = """永辉超市供货单
单据日期: 2026-07-17
商品名称 条形码 数量 单价 金额
550水 6921168509256 1箱 55.00 55.00
茶π 6921168599905 3箱 62.00 186.00
应付金额 241.00"""
        m = self.ext.extract(text)
        self.assertIn("永辉", m.supplier)
        self.assertEqual(m.bill_date, "20260717")
        self.assertEqual(m.total_amount, 241.00)
        self.assertTrue(m.is_complete())

    def test_all_missing(self):
        text = "asdfgh 12345"
        m = self.ext.extract(text)
        self.assertEqual(m.supplier, "")
        self.assertEqual(m.bill_date, "")
        self.assertEqual(m.total_amount, 0.0)
        self.assertFalse(m.is_complete())


class TestSanitize(unittest.TestCase):
    def test_windows_illegal_chars(self):
        self.assertEqual(sanitize_for_filename("a/b\\c:d*e?f\"g<h>i|j"), "a_b_c_d_e_f_g_h_i_j")

    def test_empty(self):
        self.assertEqual(sanitize_for_filename(""), "")

    def test_normal(self):
        self.assertEqual(sanitize_for_filename("永辉超市"), "永辉超市")


if __name__ == '__main__':
    unittest.main()