<?php
namespace model;
use \model;

class dataAnalyst extends model
{
    public function __construct ()
    {
        parent::__construct();
    }

    /**
     * 获取指定工厂关联的资源文件列表
     */
    public function getResourceFilesByFacIds($facIds)
    {
        if(empty($facIds)) return [];
    
        $wdzy = new \model\wdzy(); // 使用 wdzy 数据库连接，因为 resource 表在那里
        
        // 1. 获取工厂对应的资源库工厂ID
        $maps = $this->db->select('factory', ['fac_id', 'fac_resource_facid'], ['fac_id' => $facIds]);
        $resFacIds = array_filter(array_column($maps, 'fac_resource_facid'));
        
        if(empty($resFacIds)) return [];

        // 2. 查询资源文件
        $rows = $wdzy->db->select('resource', 
            ['Id', 'FileName', 'ResourceState', 'CreationTime'], 
            [
                'ResourceFactoryId' => $resFacIds,
                'isDeleted' => 0,
                'ResourceState' => 199 
            ]
        );
        
        // 格式化状态描述
        foreach($rows as &$row) {
            $row['ResourceStateDesc'] = $this->getResourceStateDesc($row['ResourceState']);
        }
        
        return $rows;
    }

    private function getResourceStateDesc($state) {
        $map = [
            0 => '待解析', 199 => '解析完成', 4 => '异常'
        ];
        return $map[$state] ?? '未知';
    }

    

    /**
     * 对比逻辑 - 以资源文件为维度
     * @param array $gaIds 零件分类ID数组
     * @param array $resIds 资源文件ID数组 (resource.Id)
     */
    public function compareData($gaIds, $resIds)
    {
        if(empty($gaIds) || empty($resIds)) return [];

        $join = [
			'[><]oe_numidx(onm)'=>['oe.oe_id'=>'on_oe_id']
		];
        $systemNumbers = $this->db->select('oe_item(oe)', $join, ['onm.on_number', 'onm.on_formart'], [
            'oe.oe_cate_id' => $gaIds,
			'GROUP' => 'onm.on_formart'
        ]);
    
        $sysNumSet = [];
        foreach($systemNumbers as $row) {
            $num = trim(strtoupper($row['on_formart']));
			if($num) $sysNumSet[$num] = true; 
        }

        $wdzy = new \model\wdzy();
        
        // 获取资源文件ID到文件名的映射，用于后续显示
        $resFiles = $wdzy->db->select('resource', ['Id', 'FileName'], ['Id' => $resIds]);
        $resFileMap = array_column($resFiles, 'FileName', 'Id');

        // 获取资源库中的所有号码，并记录它们所属的文件ID
        $resNumbersRaw = $wdzy->db->select('resourcenumber(n)', 
            ['[><]resource(r)' => ['n.ResourceId' => 'Id']], 
            ['n.FormatNumber', 'r.Id(ResFileId)'], // 获取资源文件ID
            [
                'r.Id' => $resIds,
                'n.isDeleted' => 0,
                'r.isDeleted' => 0
            ]
        );

        $resNumSet = [];          // 所有在资源库中出现的号码集合 (用于快速判断存在性)
        $resNumSourceMap = [];    // 号码 -> [文件ID列表] 的映射: ['NUM1' => [12, 15]]

        foreach($resNumbersRaw as $row) {
            $num = trim(strtoupper($row['FormatNumber']));
            $fileId = $row['ResFileId'];
            
            if($num) {
                $resNumSet[$num] = true;
                
                if(!isset($resNumSourceMap[$num])) {
                    $resNumSourceMap[$num] = [];
                }
                // 避免重复添加同一个文件ID
                if(!in_array($fileId, $resNumSourceMap[$num])) {
                    $resNumSourceMap[$num][] = $fileId;
                }
            }
        }

        // 对比并生成结果 ---
        $result = [];

        // 1. 共同拥有 
        $common = array_intersect_key($sysNumSet, $resNumSet);
        foreach($common as $num => $val) {
            // 获取来源文件名
            $sourceFiles = [];
            if(isset($resNumSourceMap[$num])) {
                foreach($resNumSourceMap[$num] as $fid) {
                    if(isset($resFileMap[$fid])) {
                        $sourceFiles[] = $resFileMap[$fid];
                    }
                }
            }
            
            $result[] = [
                'type' => 1, // 共有
                'number' => $num,
                'in_system' => 'Y',
                'in_resource' => 'Y',
                'source_files' => $sourceFiles // 数组格式，前端处理
            ];
        }

       
        // 2.1 零件库没有，资源库有 (原 type 2)
        $onlyRes = array_diff_key($resNumSet, $sysNumSet);
        foreach($onlyRes as $num => $val) {
             $sourceFiles = [];
            if(isset($resNumSourceMap[$num])) {
                foreach($resNumSourceMap[$num] as $fid) {
                    if(isset($resFileMap[$fid])) {
                        $sourceFiles[] = $resFileMap[$fid];
                    }
                }
            }

            $result[] = [
                'type' => 2, 
                'number' => $num,
                'in_system' => 'N',
                'in_resource' => 'Y',
                'source_files' => $sourceFiles
            ];
        }

        //零件库有，资源库没有
        $onlySys = array_diff_key($sysNumSet, $resNumSet);
        foreach($onlySys as $num => $val) {
            $result[] = [
                'type' => 3, 
                'number' => $num,
                'in_system' => 'Y',
                'in_resource' => 'N',
                'source_files' => []
            ];
        }

        usort($result, function($a, $b) {
            if ($a['type'] != $b['type']) {
                return $a['type'] - $b['type'];
            }
            return strcmp($a['number'], $b['number']);
        });

        return $result;
    }

	 /**
     * 对比逻辑 - 以工厂为维度
     * @param array $gaIds 零件分类ID数组
     * @param array $resIds 资源文件ID数组 (resource.Id)
     */
    public function compareDataByFactory($gaIds, $resIds)
    {
        if(empty($gaIds) || empty($resIds)) return [];

        // --- 第一步：获取系统内该分类下的所有标准号码 (System Numbers) ---
        $join = [
			'[><]oe_numidx(onm)'=>['oe.oe_id'=>'on_oe_id']
		];
        $systemNumbers = $this->db->select('oe_item(oe)', $join, ['onm.on_number', 'onm.on_formart'], [
            'oe.oe_cate_id' => $gaIds,
            'onm.on_formart[!]' => null,
			'GROUP'=>'onm.on_number'
        ]);
    
        $sysNumSet = [];
        $sysNumInfo = []; 
        foreach($systemNumbers as $row) {
            $num = trim(strtoupper($row['on_formart']));
            if($num) {
                $sysNumSet[$num] = true;
                // 缓存一些基本信息，如原始OE号
                if(!isset($sysNumInfo[$num])) {
                    $sysNumInfo[$num] = $row['on_number'];
                }
            }
        }

        if(empty($sysNumSet)) {
            return []; // 如果系统里没有这个分类的标准号，无法对比
        }

        // --- 第二步：获取选定资源文件中的所有号码，并按工厂分组 ---
        $wdzy = new \model\wdzy();
        
        $resNumbersRaw = $wdzy->db->select('resourcenumber(n)', 
            [
                '[><]resource(r)' => ['n.ResourceId' => 'Id'],
            ],
            ['n.FormatNumber', 'r.ResourceFactoryId'], 
            [
                'r.Id' => $resIds,
                'n.isDeleted' => 0,
                'r.isDeleted' => 0,
                'r.ResourceFactoryId[!]' => null // 确保能关联到本地工厂
            ]
        );

        // 构建数据结构: $factoryData[fac_id] = { name: '', numbers: [] }
        $factoryData = [];
        
        // 这里只显示有匹配资源的工厂）
        foreach($resNumbersRaw as $row) {
            $facId = $row['ResourceFactoryId'];
			$fac_name = $this->db->get('factory', 'fac_name', ['fac_resource_facid'=>$facId]);
            $num = trim(strtoupper($row['FormatNumber']));
            
            if(!isset($factoryData[$facId])) {
                $factoryData[$facId] = [
                    'fac_id' => $facId,
					'fac_name'=>$fac_name,
                    'resNumSet' => [],
                    'common' => [],      // 共同拥有
                    'onlyRes' => [],     // 缺件(资源有)
                    'onlySys' => []      // 冗余(我有)
                ];
            }
            
            if($num) {
                $factoryData[$facId]['resNumSet'][$num] = true;
            }
        }

        // --- 第三步：对每个工厂进行对比计算 ---
        $result = [];
        
        foreach($factoryData as $facId => &$fData) {
            $resSet = $fData['resNumSet'];
            
            // 1. 共同拥有
            $commonKeys = array_intersect_key($sysNumSet, $resSet);
            foreach($commonKeys as $num => $val) {
                $fData['common'][] = [
                    'number' => $num,
                    'oe' => $sysNumInfo[$num] ?? ''
                ];
            }
            
            // 2. 我没有，资源库有 (缺件)
            $onlyResKeys = array_diff_key($resSet, $sysNumSet);
            foreach($onlyResKeys as $num => $val) {
                $fData['onlyRes'][] = [
                    'number' => $num,
                    'oe' => '-'
                ];
            }
            
            // 3. 我有，资源库没有 (冗余/缺失)
            $onlySysKeys = array_diff_key($sysNumSet, $resSet);
            foreach($onlySysKeys as $num => $val) {
                $fData['onlySys'][] = [
                    'number' => $num,
                    'oe' => $sysNumInfo[$num] ?? ''
                ];
            }
            
            // 排序：为了前端展示美观，可以对每个列表内部按号码排序
            usort($fData['common'], function($a, $b) { return strcmp($a['number'], $b['number']); });
            usort($fData['onlyRes'], function($a, $b) { return strcmp($a['number'], $b['number']); });
            usort($fData['onlySys'], function($a, $b) { return strcmp($a['number'], $b['number']); });
            
            // 统计数量
            $fData['stats'] = [
                'common_count' => count($fData['common']),
                'onlyRes_count' => count($fData['onlyRes']),
                'onlySys_count' => count($fData['onlySys']),
                'total_sys' => count($sysNumSet),
                'coverage_rate' => count($sysNumSet) > 0 ? round((count($fData['common']) / count($sysNumSet)) * 100, 2) . '%' : '0%'
            ];
            
            $result[] = $fData;
        }
        
        // 按工厂名称排序结果
        usort($result, function($a, $b) {
            return strcmp($a['fac_name'], $b['fac_name']);
        });

        return $result;
    }

}