<?php

namespace App\Services;

use App\Models\Items\Item;
use Illuminate\Pagination\LengthAwarePaginator;

class ItemManagementService
{
    /**
     * 품목 목록 조회 (검색, 유형 필터, 페이지네이션)
     */
    public function getItemList(array $filters): LengthAwarePaginator
    {
        $tenantId = session('selected_tenant_id');
        $search = $filters['search'] ?? null;
        $itemType = $filters['item_type'] ?? null;
        $perPage = $filters['per_page'] ?? 50;

        return Item::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->search($search)
            ->active()
            ->when($itemType, function ($query, $types) {
                $typeList = explode(',', $types);
                $query->whereIn('item_type', $typeList);
            })
            ->orderBy('code')
            ->paginate($perPage);
    }

    /**
     * BOM 재귀 트리 조회
     */
    public function getBomTree(int $itemId, int $maxDepth = 10): array
    {
        $item = Item::withoutGlobalScopes()
            ->where('tenant_id', session('selected_tenant_id'))
            ->with('details')
            ->findOrFail($itemId);

        return $this->buildBomNode($item, 0, $maxDepth, []);
    }

    /**
     * 품목 상세 조회 (1depth BOM + 파일 + 절곡정보)
     */
    public function getItemDetail(int $itemId): array
    {
        $tenantId = session('selected_tenant_id');

        $item = Item::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->with(['details', 'category', 'files'])
            ->findOrFail($itemId);

        // BOM 1depth: 직접 연결된 자식 품목만
        $bomChildren = [];
        $bomData = $item->bom ?? [];
        if (! empty($bomData)) {
            $childIds = array_column($bomData, 'child_item_id');
            $children = Item::withoutGlobalScopes()
                ->where('tenant_id', $tenantId)
                ->whereIn('id', $childIds)
                ->get(['id', 'code', 'name', 'item_type', 'unit'])
                ->keyBy('id');

            foreach ($bomData as $bom) {
                $child = $children->get($bom['child_item_id']);
                if ($child) {
                    $bomChildren[] = [
                        'id' => $child->id,
                        'code' => $child->code,
                        'name' => $child->name,
                        'item_type' => $child->item_type,
                        'unit' => $child->unit,
                        'quantity' => $bom['quantity'] ?? 1,
                    ];
                }
            }
        }

        return [
            'item' => $item,
            'bom_children' => $bomChildren,
        ];
    }

    // ── Private ──

    private function buildBomNode(Item $item, int $depth, int $maxDepth, array $visited): array
    {
        // 순환 참조 방지: visited 배열 + maxDepth 이중 안전장치
        if (in_array($item->id, $visited) || $depth >= $maxDepth) {
            return $this->formatNode($item, $depth, []);
        }

        $visited[] = $item->id;
        $children = [];

        $bomData = $item->bom ?? [];
        if (! empty($bomData)) {
            $childIds = array_column($bomData, 'child_item_id');
            $childItems = Item::withoutGlobalScopes()
                ->where('tenant_id', session('selected_tenant_id'))
                ->whereIn('id', $childIds)
                ->get()
                ->keyBy('id');

            foreach ($bomData as $bom) {
                $childItem = $childItems->get($bom['child_item_id']);
                if ($childItem) {
                    $childNode = $this->buildBomNode($childItem, $depth + 1, $maxDepth, $visited);
                    $childNode['quantity'] = $bom['quantity'] ?? 1;
                    $children[] = $childNode;
                }
            }
        }

        return $this->formatNode($item, $depth, $children);
    }

    private function formatNode(Item $item, int $depth, array $children): array
    {
        return [
            'id' => $item->id,
            'code' => $item->code,
            'name' => $item->name,
            'item_type' => $item->item_type,
            'unit' => $item->unit,
            'depth' => $depth,
            'has_children' => count($children) > 0,
            'children' => $children,
        ];
    }
}
