<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\DocumentTemplate;
use App\Models\DocumentTemplateApprovalLine;
use App\Models\DocumentTemplateBasicField;
use App\Models\DocumentTemplateColumn;
use App\Models\DocumentTemplateLink;
use App\Models\DocumentTemplateLinkValue;
use App\Models\DocumentTemplateSection;
use App\Models\DocumentTemplateSectionField;
use App\Models\DocumentTemplateSectionItem;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class DocumentTemplateApiController extends Controller
{
    /**
     * 목록 조회 (HTMX 테이블)
     */
    public function index(Request $request): View
    {
        $query = DocumentTemplate::query()
            ->withCount(['sections', 'columns']);

        // 선택된 테넌트 필터
        $tenantId = session('selected_tenant_id');
        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        // 슈퍼관리자 휴지통 조회
        $showTrashed = $request->filled('trashed') && auth()->user()?->is_super_admin;
        if ($showTrashed) {
            $query->onlyTrashed();
        }

        // 검색 (양식명, 제목, 분류, 연결 품목)
        if ($search = $request->input('search')) {
            // 연결 품목 검색을 위해 품목명으로 ID 조회
            $matchingItemIds = \App\Models\Items\Item::where('name', 'like', "%{$search}%")
                ->pluck('id')
                ->toArray();

            $query->where(function ($q) use ($search, $matchingItemIds) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('title', 'like', "%{$search}%")
                    ->orWhere('category', 'like', "%{$search}%");

                // 연결 품목 검색 (JSON 배열에서 매칭)
                foreach ($matchingItemIds as $itemId) {
                    $q->orWhereJsonContains('linked_item_ids', $itemId);
                }
            });
        }

        // 카테고리 필터
        if ($category = $request->input('category')) {
            $query->where('category', $category);
        }

        // 활성 상태 필터
        if ($request->filled('is_active') && ! $showTrashed) {
            $query->where('is_active', $request->boolean('is_active'));
        }

        $templates = $query->orderBy('updated_at', 'desc')
            ->paginate($request->input('per_page', 10));

        // 연결된 품목 ID 수집 및 품목명 조회
        $allItemIds = $templates->pluck('linked_item_ids')->flatten()->filter()->unique()->values()->toArray();
        $itemNames = [];
        if (! empty($allItemIds)) {
            $itemNames = \App\Models\Items\Item::whereIn('id', $allItemIds)
                ->pluck('name', 'id')
                ->toArray();
        }

        // 분류 코드 → 이름 매핑
        $tenantId = session('selected_tenant_id');
        $categoryNames = DB::table('common_codes')
            ->where('code_group', 'document_category')
            ->where('is_active', true)
            ->where(function ($q) use ($tenantId) {
                $q->whereNull('tenant_id');
                if ($tenantId) {
                    $q->orWhere('tenant_id', $tenantId);
                }
            })
            ->pluck('name', 'code')
            ->toArray();

        return view('document-templates.partials.table', compact('templates', 'showTrashed', 'itemNames', 'categoryNames'));
    }

    /**
     * 단일 조회
     */
    public function show(int $id): JsonResponse
    {
        $template = DocumentTemplate::with([
            'approvalLines',
            'basicFields',
            'sections.items',
            'columns',
            'sectionFields',
            'links.linkValues',
        ])->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $template,
        ]);
    }

    /**
     * 생성
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'category' => 'nullable|string|max:50',
            'title' => 'nullable|string|max:200',
            'company_name' => 'nullable|string|max:100',
            'company_address' => 'nullable|string|max:255',
            'company_contact' => 'nullable|string|max:100',
            'footer_remark_label' => 'nullable|string|max:50',
            'footer_judgement_label' => 'nullable|string|max:50',
            'footer_judgement_options' => 'nullable|array',
            'is_active' => 'boolean',
            'linked_item_ids' => 'nullable|array',
            'linked_item_ids.*' => 'integer',
            'linked_process_id' => 'nullable|integer',
            // 관계 데이터
            'approval_lines' => 'nullable|array',
            'basic_fields' => 'nullable|array',
            'sections' => 'nullable|array',
            'columns' => 'nullable|array',
            'section_fields' => 'nullable|array',
            'template_links' => 'nullable|array',
        ]);

        // 동일 분류 내 연결품목 중복 검증
        $category = $validated['category'] ?? null;
        $newItemIds = $this->extractLinkedItemIds($validated);
        $duplicateError = $this->checkLinkedItemDuplicates($category, $newItemIds);
        if ($duplicateError) {
            return $duplicateError;
        }

        try {
            DB::beginTransaction();

            $template = DocumentTemplate::create([
                'tenant_id' => session('selected_tenant_id'),
                'name' => $validated['name'],
                'category' => $validated['category'] ?? null,
                'title' => $validated['title'] ?? null,
                'company_name' => $validated['company_name'] ?? '경동기업',
                'company_address' => $validated['company_address'] ?? null,
                'company_contact' => $validated['company_contact'] ?? null,
                'footer_remark_label' => $validated['footer_remark_label'] ?? '부적합 내용',
                'footer_judgement_label' => $validated['footer_judgement_label'] ?? '종합판정',
                'footer_judgement_options' => $validated['footer_judgement_options'] ?? ['적합', '부적합'],
                'is_active' => $validated['is_active'] ?? true,
                'linked_item_ids' => $validated['linked_item_ids'] ?? null,
                'linked_process_id' => $validated['linked_process_id'] ?? null,
            ]);

            // 관계 데이터 저장
            $this->saveRelations($template, $validated);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => '문서양식이 생성되었습니다.',
                'data' => $template->load(['approvalLines', 'basicFields', 'sections.items', 'columns', 'sectionFields', 'links.linkValues']),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => '생성 중 오류가 발생했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 수정
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $template = DocumentTemplate::findOrFail($id);

        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'category' => 'nullable|string|max:50',
            'title' => 'nullable|string|max:200',
            'company_name' => 'nullable|string|max:100',
            'company_address' => 'nullable|string|max:255',
            'company_contact' => 'nullable|string|max:100',
            'footer_remark_label' => 'nullable|string|max:50',
            'footer_judgement_label' => 'nullable|string|max:50',
            'footer_judgement_options' => 'nullable|array',
            'is_active' => 'boolean',
            'linked_item_ids' => 'nullable|array',
            'linked_item_ids.*' => 'integer',
            'linked_process_id' => 'nullable|integer',
            // 관계 데이터
            'approval_lines' => 'nullable|array',
            'basic_fields' => 'nullable|array',
            'sections' => 'nullable|array',
            'columns' => 'nullable|array',
            'section_fields' => 'nullable|array',
            'template_links' => 'nullable|array',
        ]);

        // 동일 분류 내 연결품목 중복 검증
        $category = $validated['category'] ?? null;
        $newItemIds = $this->extractLinkedItemIds($validated);
        $duplicateError = $this->checkLinkedItemDuplicates($category, $newItemIds, $template->id);
        if ($duplicateError) {
            return $duplicateError;
        }

        try {
            DB::beginTransaction();

            $template->update([
                'name' => $validated['name'],
                'category' => $validated['category'] ?? null,
                'title' => $validated['title'] ?? null,
                'company_name' => $validated['company_name'] ?? null,
                'company_address' => $validated['company_address'] ?? null,
                'company_contact' => $validated['company_contact'] ?? null,
                'footer_remark_label' => $validated['footer_remark_label'] ?? '부적합 내용',
                'footer_judgement_label' => $validated['footer_judgement_label'] ?? '종합판정',
                'footer_judgement_options' => $validated['footer_judgement_options'] ?? ['적합', '부적합'],
                'is_active' => $validated['is_active'] ?? true,
                'linked_item_ids' => $validated['linked_item_ids'] ?? null,
                'linked_process_id' => $validated['linked_process_id'] ?? null,
            ]);

            // 관계 데이터 저장 (기존 데이터 삭제 후 재생성)
            $this->saveRelations($template, $validated, true);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => '문서양식이 수정되었습니다.',
                'data' => $template->fresh(['approvalLines', 'basicFields', 'sections.items', 'columns', 'sectionFields', 'links.linkValues']),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => '수정 중 오류가 발생했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 삭제 (소프트 삭제)
     */
    public function destroy(int $id): JsonResponse
    {
        $template = DocumentTemplate::findOrFail($id);
        $template->update(['deleted_by' => auth()->id()]);
        $template->delete();

        return response()->json([
            'success' => true,
            'message' => '문서양식이 삭제되었습니다.',
        ]);
    }

    /**
     * 영구삭제 (슈퍼관리자 전용)
     */
    public function forceDestroy(int $id): JsonResponse
    {
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '슈퍼관리자만 영구 삭제할 수 있습니다.',
            ], 403);
        }

        $tenantId = session('selected_tenant_id');
        $template = DocumentTemplate::withTrashed()
            ->where('tenant_id', $tenantId)
            ->findOrFail($id);

        // 이 양식을 참조하는 문서가 있는지 확인 (소프트삭제 포함)
        $documentCount = \App\Models\Documents\Document::withTrashed()
            ->where('template_id', $template->id)
            ->count();

        if ($documentCount > 0) {
            return response()->json([
                'success' => false,
                'message' => "이 양식을 사용한 문서가 {$documentCount}건 있어 영구 삭제할 수 없습니다. 문서를 먼저 삭제해주세요.",
            ], 422);
        }

        // 관련 데이터도 영구삭제
        $template->approvalLines()->delete();
        $template->basicFields()->delete();
        $template->sections()->each(function ($section) {
            $section->items()->delete();
            $section->delete();
        });
        $template->columns()->delete();
        $template->sectionFields()->delete();
        $template->links()->delete(); // cascade로 linkValues도 삭제
        $template->forceDelete();

        return response()->json([
            'success' => true,
            'message' => '문서양식이 영구 삭제되었습니다.',
        ]);
    }

    /**
     * 삭제된 문서양식 복원 (슈퍼관리자 전용)
     */
    public function restore(int $id): JsonResponse
    {
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '슈퍼관리자만 복원할 수 있습니다.',
            ], 403);
        }

        $tenantId = session('selected_tenant_id');
        $template = DocumentTemplate::onlyTrashed()
            ->where('tenant_id', $tenantId)
            ->findOrFail($id);

        $template->update(['deleted_by' => null]);
        $template->restore();

        return response()->json([
            'success' => true,
            'message' => '문서양식이 복원되었습니다.',
        ]);
    }

    /**
     * 활성 상태 토글
     */
    public function toggleActive(int $id): JsonResponse
    {
        $template = DocumentTemplate::findOrFail($id);
        $template->update(['is_active' => ! $template->is_active]);

        return response()->json([
            'success' => true,
            'message' => $template->is_active ? '활성화되었습니다.' : '비활성화되었습니다.',
            'is_active' => $template->is_active,
        ]);
    }

    /**
     * 양식 복제
     */
    public function duplicate(Request $request, int $id): JsonResponse
    {
        $source = DocumentTemplate::with([
            'approvalLines',
            'basicFields',
            'sections.items',
            'columns',
            'sectionFields',
            'links.linkValues',
        ])->findOrFail($id);

        $newName = $request->input('name', $source->name.' (복사)');

        try {
            DB::beginTransaction();

            $newTemplate = DocumentTemplate::create([
                'tenant_id' => $source->tenant_id,
                'name' => $newName,
                'category' => $source->category,
                'title' => $source->title,
                'company_name' => $source->company_name,
                'company_address' => $source->company_address,
                'company_contact' => $source->company_contact,
                'footer_remark_label' => $source->footer_remark_label,
                'footer_judgement_label' => $source->footer_judgement_label,
                'footer_judgement_options' => $source->footer_judgement_options,
                'is_active' => false,
                'linked_item_ids' => null, // 연결품목은 복사하지 않음 (중복 방지)
                'linked_process_id' => null,
            ]);

            foreach ($source->approvalLines as $line) {
                DocumentTemplateApprovalLine::create([
                    'template_id' => $newTemplate->id,
                    'name' => $line->name,
                    'dept' => $line->dept,
                    'role' => $line->role,
                    'user_id' => $line->user_id,
                    'sort_order' => $line->sort_order,
                ]);
            }

            foreach ($source->basicFields as $field) {
                DocumentTemplateBasicField::create([
                    'template_id' => $newTemplate->id,
                    'label' => $field->label,
                    'field_type' => $field->field_type,
                    'default_value' => $field->default_value,
                    'sort_order' => $field->sort_order,
                ]);
            }

            foreach ($source->sections as $section) {
                $newSection = DocumentTemplateSection::create([
                    'template_id' => $newTemplate->id,
                    'title' => $section->title,
                    'image_path' => $section->image_path,
                    'sort_order' => $section->sort_order,
                ]);

                foreach ($section->items as $item) {
                    DocumentTemplateSectionItem::create([
                        'section_id' => $newSection->id,
                        'category' => $item->category,
                        'item' => $item->item,
                        'standard' => $item->standard,
                        'tolerance' => $item->tolerance,
                        'standard_criteria' => $item->standard_criteria,
                        'method' => $item->method,
                        'measurement_type' => $item->measurement_type,
                        'frequency_n' => $item->frequency_n,
                        'frequency_c' => $item->frequency_c,
                        'frequency' => $item->frequency,
                        'regulation' => $item->regulation,
                        'sort_order' => $item->sort_order,
                    ]);
                }
            }

            foreach ($source->columns as $col) {
                DocumentTemplateColumn::create([
                    'template_id' => $newTemplate->id,
                    'label' => $col->label,
                    'width' => $col->width,
                    'column_type' => $col->column_type,
                    'group_name' => $col->group_name,
                    'sub_labels' => $col->sub_labels,
                    'sort_order' => $col->sort_order,
                ]);
            }

            // 검사 기준서 동적 필드 복제
            foreach ($source->sectionFields as $field) {
                DocumentTemplateSectionField::create([
                    'template_id' => $newTemplate->id,
                    'field_key' => $field->field_key,
                    'label' => $field->label,
                    'field_type' => $field->field_type,
                    'options' => $field->options,
                    'width' => $field->width,
                    'is_required' => $field->is_required,
                    'sort_order' => $field->sort_order,
                ]);
            }

            // 외부 키 매핑 복제 (구조만 복사, 연결 값은 제외 - 중복 방지)
            foreach ($source->links as $link) {
                DocumentTemplateLink::create([
                    'template_id' => $newTemplate->id,
                    'link_key' => $link->link_key,
                    'label' => $link->label,
                    'link_type' => $link->link_type,
                    'source_table' => $link->source_table,
                    'search_params' => $link->search_params,
                    'display_fields' => $link->display_fields,
                    'is_required' => $link->is_required,
                    'sort_order' => $link->sort_order,
                ]);
                // linkValues는 복사하지 않음 (동일 분류 내 연결품목 중복 방지)
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => "'{$newName}' 양식이 복제되었습니다.",
                'data' => $newTemplate->load(['approvalLines', 'basicFields', 'sections.items', 'columns']),
            ]);
        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => '복제 중 오류가 발생했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 이미지 업로드 (API 파일 저장소 연동)
     */
    public function uploadImage(Request $request): JsonResponse
    {
        $request->validate([
            'image' => 'required|image|max:5120', // 5MB
        ]);

        $apiBaseUrl = config('services.api.base_url');
        $apiKey = config('services.api.key');

        if (empty($apiBaseUrl)) {
            return response()->json([
                'success' => false,
                'message' => 'API 서버 URL이 설정되지 않았습니다.',
            ], 500);
        }

        // API 토큰 교환
        $tokenService = new \App\Services\ApiTokenService;
        $userId = auth()->id();
        $tenantId = session('selected_tenant_id', 1);

        $tokenResult = $tokenService->exchangeToken($userId, $tenantId);
        if (! $tokenResult['success']) {
            Log::error('[DocumentTemplate] API 토큰 교환 실패', [
                'error' => $tokenResult['error'] ?? '',
            ]);

            return response()->json([
                'success' => false,
                'message' => 'API 인증 실패',
            ], 500);
        }

        // API 파일 업로드 호출
        $image = $request->file('image');

        try {
            $response = Http::withToken($tokenResult['data']['access_token'])
                ->withHeaders(['X-API-KEY' => $apiKey])
                ->attach('file', file_get_contents($image->getRealPath()), $image->getClientOriginalName())
                ->post("{$apiBaseUrl}/api/v1/files/upload");

            if ($response->successful() && $response->json('success')) {
                $filePath = $response->json('data.file_path');

                return response()->json([
                    'success' => true,
                    'path' => $filePath,
                    'url' => "{$apiBaseUrl}/storage/tenants/{$filePath}",
                ]);
            }

            Log::error('[DocumentTemplate] API 파일 업로드 실패', [
                'status' => $response->status(),
                'body' => $response->json(),
            ]);

            return response()->json([
                'success' => false,
                'message' => 'API 파일 업로드 실패',
            ], 500);
        } catch (\Exception $e) {
            Log::error('[DocumentTemplate] API 파일 업로드 예외', [
                'exception' => $e->getMessage(),
            ]);

            return response()->json([
                'success' => false,
                'message' => '파일 업로드 중 오류가 발생했습니다.',
            ], 500);
        }
    }

    /**
     * 공통코드 그룹 조회 (JSON)
     */
    public function getCommonCodes(string $group): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        $codes = \App\Models\Products\CommonCode::query()
            ->where('code_group', $group)
            ->where('is_active', true)
            ->where(function ($q) use ($tenantId) {
                $q->whereNull('tenant_id');
                if ($tenantId) {
                    $q->orWhere('tenant_id', $tenantId);
                }
            })
            ->orderBy('sort_order')
            ->get(['code', 'name']);

        return response()->json([
            'success' => true,
            'data' => $codes,
        ]);
    }

    /**
     * 관계 데이터 저장 (ID 보존 upsert 방식)
     *
     * sections/columns는 기존 ID를 보존하여 document_data 참조가 깨지지 않도록 함.
     * 나머지(approval_lines, basic_fields 등)는 단순 관계라 삭제→재생성.
     */
    private function saveRelations(DocumentTemplate $template, array $data, bool $deleteExisting = false): void
    {
        // 단순 관계: 삭제 → 재생성 (document_data가 참조하지 않는 테이블)
        if ($deleteExisting) {
            $template->approvalLines()->delete();
            $template->basicFields()->delete();
            $template->sectionFields()->delete();
            $template->links()->delete();
        }

        // 결재라인
        if (! empty($data['approval_lines'])) {
            foreach ($data['approval_lines'] as $index => $line) {
                DocumentTemplateApprovalLine::create([
                    'template_id' => $template->id,
                    'name' => $line['name'] ?? '',
                    'dept' => $line['dept'] ?? '',
                    'role' => $line['role'] ?? '',
                    'user_id' => $line['user_id'] ?? null,
                    'sort_order' => $index,
                ]);
            }
        }

        // 기본 필드
        if (! empty($data['basic_fields'])) {
            foreach ($data['basic_fields'] as $index => $field) {
                DocumentTemplateBasicField::create([
                    'template_id' => $template->id,
                    'label' => $field['label'] ?? '',
                    'field_key' => $field['field_key'] ?? null,
                    'field_type' => $field['field_type'] ?? 'text',
                    'default_value' => $field['default_value'] ?? '',
                    'sort_order' => $index,
                ]);
            }
        }

        // 섹션 및 항목: ID 보존 upsert (document_data.section_id 참조 보호)
        if (isset($data['sections'])) {
            $incomingIds = collect($data['sections'])->pluck('id')->filter()->toArray();
            // 요청에 없는 섹션만 삭제 (cascade로 items도 삭제)
            if ($deleteExisting) {
                $template->sections()->whereNotIn('id', $incomingIds)->each(function ($section) {
                    $section->items()->delete();
                    $section->delete();
                });
            }

            foreach ($data['sections'] as $sIndex => $section) {
                $sectionData = [
                    'title' => $section['title'] ?? '',
                    'image_path' => $section['image_path'] ?? null,
                    'sort_order' => $sIndex,
                ];

                if (! empty($section['id']) && $template->sections()->where('id', $section['id'])->exists()) {
                    $existing = $template->sections()->where('id', $section['id'])->first();
                    $existing->update($sectionData);
                    $savedSection = $existing;
                } else {
                    $savedSection = DocumentTemplateSection::create(array_merge(
                        ['template_id' => $template->id],
                        $sectionData
                    ));
                }

                // 섹션 항목 upsert
                if (isset($section['items'])) {
                    $itemIncomingIds = collect($section['items'])->pluck('id')->filter()->toArray();
                    $savedSection->items()->whereNotIn('id', $itemIncomingIds)->delete();

                    foreach ($section['items'] as $iIndex => $item) {
                        $itemData = [
                            'category' => $item['category'] ?? '',
                            'item' => $item['item'] ?? '',
                            'standard' => $item['standard'] ?? '',
                            'tolerance' => $item['tolerance'] ?? null,
                            'standard_criteria' => $item['standard_criteria'] ?? null,
                            'method' => $item['method'] ?? '',
                            'measurement_type' => $item['measurement_type'] ?? null,
                            'frequency_n' => $item['frequency_n'] ?? null,
                            'frequency_c' => $item['frequency_c'] ?? null,
                            'frequency' => $item['frequency'] ?? '',
                            'regulation' => $item['regulation'] ?? '',
                            'field_values' => $item['field_values'] ?? null,
                            'sort_order' => $iIndex,
                        ];

                        if (! empty($item['id']) && $savedSection->items()->where('id', $item['id'])->exists()) {
                            $savedSection->items()->where('id', $item['id'])->update($itemData);
                        } else {
                            DocumentTemplateSectionItem::create(array_merge(
                                ['section_id' => $savedSection->id],
                                $itemData
                            ));
                        }
                    }
                }
            }
        }

        // 컬럼: ID 보존 upsert (document_data.column_id 참조 보호)
        if (isset($data['columns'])) {
            $incomingIds = collect($data['columns'])->pluck('id')->filter()->toArray();
            if ($deleteExisting) {
                $template->columns()->whereNotIn('id', $incomingIds)->delete();
            }

            foreach ($data['columns'] as $index => $column) {
                $colData = [
                    'label' => $column['label'] ?? '',
                    'width' => $column['width'] ?? '100px',
                    'column_type' => $column['column_type'] ?? 'text',
                    'group_name' => $column['group_name'] ?? null,
                    'sub_labels' => $column['sub_labels'] ?? null,
                    'sort_order' => $index,
                ];

                if (! empty($column['id']) && $template->columns()->where('id', $column['id'])->exists()) {
                    $template->columns()->where('id', $column['id'])->update($colData);
                } else {
                    DocumentTemplateColumn::create(array_merge(
                        ['template_id' => $template->id],
                        $colData
                    ));
                }
            }
        }

        // 검사 기준서 동적 필드 정의
        if (! empty($data['section_fields'])) {
            foreach ($data['section_fields'] as $index => $field) {
                DocumentTemplateSectionField::create([
                    'template_id' => $template->id,
                    'field_key' => $field['field_key'] ?? '',
                    'label' => $field['label'] ?? '',
                    'field_type' => $field['field_type'] ?? 'text',
                    'options' => $field['options'] ?? null,
                    'width' => $field['width'] ?? '100px',
                    'is_required' => $field['is_required'] ?? false,
                    'sort_order' => $index,
                ]);
            }
        }

        // 외부 키 매핑 + 연결 값
        if (! empty($data['template_links'])) {
            foreach ($data['template_links'] as $index => $link) {
                $newLink = DocumentTemplateLink::create([
                    'template_id' => $template->id,
                    'link_key' => $link['link_key'] ?? '',
                    'label' => $link['label'] ?? '',
                    'link_type' => $link['link_type'] ?? 'single',
                    'source_table' => $link['source_table'] ?? '',
                    'search_params' => $link['search_params'] ?? null,
                    'display_fields' => $link['display_fields'] ?? null,
                    'is_required' => $link['is_required'] ?? false,
                    'sort_order' => $index,
                ]);

                // 연결 값 저장
                if (! empty($link['values'])) {
                    foreach ($link['values'] as $vIndex => $value) {
                        DocumentTemplateLinkValue::create([
                            'template_id' => $template->id,
                            'link_id' => $newLink->id,
                            'linkable_id' => $value['linkable_id'] ?? $value['id'] ?? $value,
                            'sort_order' => $vIndex,
                            'created_at' => now(),
                        ]);
                    }
                }
            }
        }
    }

    /**
     * 요청 데이터에서 연결 품목 ID 추출 (레거시 + 신규 방식)
     */
    private function extractLinkedItemIds(array $data): array
    {
        $itemIds = collect($data['linked_item_ids'] ?? []);

        if (! empty($data['template_links'])) {
            foreach ($data['template_links'] as $link) {
                if (($link['source_table'] ?? '') === 'items' && ! empty($link['values'])) {
                    foreach ($link['values'] as $value) {
                        $id = $value['linkable_id'] ?? $value['id'] ?? (is_numeric($value) ? $value : null);
                        if ($id) {
                            $itemIds->push((int) $id);
                        }
                    }
                }
            }
        }

        return $itemIds->filter()->unique()->values()->all();
    }

    /**
     * 동일 분류 내 연결품목 중복 검증 → 중복 시 JsonResponse 반환
     */
    private function checkLinkedItemDuplicates(?string $category, array $newItemIds, ?int $excludeTemplateId = null): ?JsonResponse
    {
        if (empty($newItemIds) || empty($category)) {
            return null;
        }

        $tenantId = session('selected_tenant_id');

        $query = DocumentTemplate::where('tenant_id', $tenantId)
            ->where('category', $category);

        if ($excludeTemplateId) {
            $query->where('id', '!=', $excludeTemplateId);
        }

        $otherTemplates = $query->get(['id', 'name', 'linked_item_ids']);

        $duplicates = [];

        foreach ($otherTemplates as $template) {
            // 레거시 linked_item_ids
            $otherItemIds = collect($template->linked_item_ids ?? []);

            // 신규 link_values (source_table = 'items')
            $linkValueItemIds = DocumentTemplateLinkValue::where('template_id', $template->id)
                ->whereIn('linkable_id', $newItemIds)
                ->whereHas('link', fn ($q) => $q->where('source_table', 'items'))
                ->pluck('linkable_id');

            $otherItemIds = $otherItemIds->merge($linkValueItemIds)->unique();
            $overlap = $otherItemIds->intersect($newItemIds);

            if ($overlap->isNotEmpty()) {
                $duplicates[] = [
                    'template_name' => $template->name,
                    'item_ids' => $overlap->values()->toArray(),
                ];
            }
        }

        if (empty($duplicates)) {
            return null;
        }

        // 품목명 조회
        $allDupItemIds = collect($duplicates)->pluck('item_ids')->flatten()->unique();
        $itemNames = \App\Models\Items\Item::whereIn('id', $allDupItemIds)
            ->pluck('name', 'id')
            ->toArray();

        $messages = [];
        foreach ($duplicates as $dup) {
            $names = collect($dup['item_ids'])
                ->map(fn ($id) => $itemNames[$id] ?? "ID:{$id}")
                ->join(', ');
            $messages[] = "'{$dup['template_name']}' 양식에 이미 연결된 품목: {$names}";
        }

        return response()->json([
            'success' => false,
            'message' => '동일 분류 내 연결품목이 중복됩니다.',
            'errors' => ['linked_items' => $messages],
        ], 422);
    }
}
