import json
import tempfile
import unittest
from pathlib import Path
from openpyxl import Workbook,load_workbook
from intake import execute
from verify_intake import verify_intake


class IntakeTests(unittest.TestCase):
    def setUp(self):
        self.tmp=tempfile.TemporaryDirectory();self.addCleanup(self.tmp.cleanup)
        self.base=Path(self.tmp.name);self.root=self.base/'uploads';self.root.mkdir();self.out=self.base/'out'
    def book(self,filename,rows,sheet='明细',headers=None,title=False):
        w=Workbook();ws=w.active;ws.title=sheet
        if title:ws.append(['报价说明'])
        ws.append(headers or ['物料','数量','单价','备注'])
        for row in rows:ws.append(row)
        w.save(self.root/filename)
    def test_na_autodetect_and_independent_verification(self):
        self.book('示例甲-询比价-海鲜.xlsx',[['鱼【袋】',2,'#N/A',None],['虾',2,3,None]],title=True)
        self.book('示例乙-询比价-海鲜.xlsx',[['虾',2,4,None],['鱼【袋】',2,1,None],['新增',1,'2.5',None]])
        result=execute(self.root,self.out)
        self.assertEqual(result['status'],'complete');self.assertEqual(result['na_as_missing'],1)
        ws=load_workbook(self.out/'比价结果/海鲜.xlsx').active
        row=next(r for r in ws.iter_rows(min_row=2,values_only=True) if r[0]=='鱼【袋】')
        headers=list(next(ws.values));self.assertIsNone(row[headers.index('示例甲')]);self.assertIn('#N/A',row[10]);self.assertEqual(row[3],'示例乙')
        e=json.loads((self.out/'核验依据/intake.json').read_text())['entries']
        p=self.out/'核验依据/normalized'/e[0]['normalized_file'];w=load_workbook(p);w.active['D2']=99;w.save(p)
        with self.assertRaises(AssertionError):verify_intake(self.root,self.out/'核验依据/normalized',e)
    def test_column_reordering_and_multisheet(self):
        self.book('示例甲-总报价.xlsx',[[2,'菜',1]],sheet='蔬菜556',headers=['数量','商品名称','报价'])
        p=self.root/'示例甲-总报价.xlsx';w=load_workbook(p);ws=w.create_sheet('猪肉131');ws.append(['物料','数量','单价','备注']);ws.append(['肉',1,3,None]);w.save(p)
        r=execute(self.root,self.out);self.assertEqual(set(r['completed_categories']),{'蔬菜','猪肉'})
    def test_duplicate_blocks_only_category_and_retains_rows(self):
        self.book('示例甲-调料.xlsx',[['同品',1,0,None],['同品',1,3,None]])
        self.book('示例甲-猪肉.xlsx',[['肉',1,2,None]])
        r=execute(self.root,self.out);self.assertEqual(r['blocked_categories'],['调料']);self.assertEqual(r['completed_categories'],['猪肉'])
        w=load_workbook(self.out/'核验依据/处理与待确认.xlsx');self.assertEqual(w['未出表分类原始行'].max_row,3)
    def test_other_error_and_missing_formula_are_not_missing_prices(self):
        for value in ['#REF!','=1+1']:
            with self.subTest(value=value):
                self.book('示例甲-海鲜.xlsx',[['鱼',1,value,None]])
                r=execute(self.root,self.base/('case'+str(len(value))))
                self.assertEqual(r['status'],'partial');self.assertFalse(r['completed_categories'])
    def test_nonprice_na_blocks(self):
        self.book('示例甲-海鲜.xlsx',[['鱼','#N/A',2,None]])
        r=execute(self.root,self.out);self.assertEqual(r['status'],'partial')
    def test_unknown_supplier_blocks_all_selection(self):
        self.book('未知.xlsx',[['鱼',1,2,None]])
        self.book('示例甲-猪肉.xlsx',[['肉',1,2,None]])
        r=execute(self.root,self.out);self.assertFalse(r['completed_categories']);self.assertEqual(r['raw_sheets'],2)
    def test_tie_no_implicit_priority(self):
        self.book('示例甲-海鲜.xlsx',[['鱼',1,2,None]])
        self.book('示例乙-海鲜.xlsx',[['鱼',1,2,None]])
        r=execute(self.root,self.out);self.assertEqual(r['blocked_categories'],['海鲜'])
        r=execute(self.root,self.base/'explicit',{'tie_break':{'海鲜':'示例乙'}});self.assertEqual(r['status'],'complete')
    def test_explicit_supplier_category_columns(self):
        self.book('任意文件.xlsx',[['鱼',1,2,'示例甲','海鲜']],headers=['物料','数量','单价','供应商','分类'])
        r=execute(self.root,self.out);self.assertEqual(r['completed_categories'],['海鲜'])
    def test_supplement_and_date_filename(self):
        self.book('示例甲-猪肉-20260915.xlsx',[['肉',1,2,None]])
        self.book('示例甲-猪肉补充.xlsx',[['新增肉',1,3,None]])
        r=execute(self.root,self.out);self.assertEqual(r['completed_categories'],['猪肉'])
        self.assertEqual(r['output_verification']['rows'],2)
    def test_bad_numeric_reports_affected_category(self):
        self.book('示例甲-海鲜.xlsx',[['鱼',1,'待报价',None]])
        r=execute(self.root,self.out);self.assertEqual(r['blocked_categories'],['海鲜'])
    def test_legacy_file_is_reported(self):
        (self.root/'legacy.xls').write_bytes(b'not-a-real-file')
        r=execute(self.root,self.out);self.assertEqual(r['status'],'partial');self.assertTrue(r['issues'])

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