<?php

namespace App\Http\Controllers;

use App\Models\DocumentTemplate;
use App\Models\DocumentTemplateFieldPreset;
use App\Models\Products\CommonCode;
use App\Models\Tenants\Tenant;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class DocumentTemplateController extends Controller
{
    /**
     * 문서양식 목록 페이지
     */
    public function index(Request $request): View|Response
    {
        if ($request->header('HX-Request')) {
            return response('', 200)->header('HX-Redirect', route('document-templates.index'));
        }

        return view('document-templates.index', [
            'categories' => $this->getCategories(),
        ]);
    }

    /**
     * 문서양식 생성 페이지
     */
    public function create(): View
    {
        return view('document-templates.edit', [
            'template' => null,
            'templateData' => null,
            'isCreate' => true,
            'categories' => $this->getCategories(),
            'tenant' => $this->getCurrentTenant(),
            'presets' => DocumentTemplateFieldPreset::orderBy('sort_order')->get(),
            'basicFieldKeys' => $this->getBasicFieldKeys(),
        ]);
    }

    /**
     * 문서양식 수정 페이지
     */
    public function edit(int $id): View
    {
        $template = DocumentTemplate::with([
            'approvalLines',
            'basicFields',
            'sections.items',
            'columns',
            'sectionFields',
            'links.linkValues',
        ])->findOrFail($id);

        // JavaScript용 데이터 변환
        $templateData = $this->prepareTemplateData($template);

        return view('document-templates.edit', [
            'template' => $template,
            'templateData' => $templateData,
            'isCreate' => false,
            'categories' => $this->getCategories(),
            'tenant' => $this->getCurrentTenant(),
            'presets' => DocumentTemplateFieldPreset::orderBy('sort_order')->get(),
            'basicFieldKeys' => $this->getBasicFieldKeys(),
        ]);
    }

    /**
     * 현재 선택된 테넌트 조회
     */
    private function getCurrentTenant(): ?Tenant
    {
        $tenantId = session('selected_tenant_id');

        return $tenantId ? Tenant::find($tenantId) : null;
    }

    /**
     * 기본필드 키 옵션 조회 (common_codes 기반)
     */
    private function getBasicFieldKeys(): array
    {
        return CommonCode::query()
            ->where('code_group', 'doc_template_basic_field')
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->get(['code', 'name'])
            ->toArray();
    }

    /**
     * 문서분류 목록 조회 (common_codes 기반 + 기존 데이터 폴백)
     */
    private function getCategories(): array
    {
        $tenantId = session('selected_tenant_id');

        // 1. common_codes에서 document_category 조회 (테넌트 우선, 없으면 글로벌)
        $commonCategories = DB::table('common_codes')
            ->where('code_group', 'document_category')
            ->where('is_active', true)
            ->where(function ($q) use ($tenantId) {
                if ($tenantId) {
                    $q->where('tenant_id', $tenantId)
                        ->orWhereNull('tenant_id');
                } else {
                    $q->whereNull('tenant_id');
                }
            })
            ->orderBy('sort_order')
            ->get(['code', 'name', 'tenant_id'])
            ->unique('code')  // code 기준 중복 제거 (tenant_id 있는 것이 우선)
            ->map(fn ($c) => [
                'code' => $c->code,
                'name' => $c->name,
            ])
            ->values()
            ->toArray();

        // 2. 기존 템플릿에서 사용 중인 카테고리 (common_codes에 없는 것)
        $usedCodes = array_column($commonCategories, 'code');
        $usedNames = array_column($commonCategories, 'name');

        $existingCategories = DocumentTemplate::query()
            ->where(function ($query) use ($tenantId) {
                $query->whereNull('tenant_id');
                if ($tenantId) {
                    $query->orWhere('tenant_id', $tenantId);
                }
            })
            ->whereNotNull('category')
            ->where('category', '!=', '')
            ->whereNotIn('category', $usedCodes)  // code로 사용된 것 제외
            ->whereNotIn('category', $usedNames)  // name으로 사용된 것 제외
            ->distinct()
            ->orderBy('category')
            ->pluck('category')
            ->map(fn ($c) => ['code' => $c, 'name' => $c])
            ->toArray();

        return array_merge($commonCategories, $existingCategories);
    }

    /**
     * JavaScript용 템플릿 데이터 준비
     */
    private function prepareTemplateData(DocumentTemplate $template): array
    {
        return [
            'name' => $template->name,
            'category' => $template->category,
            'title' => $template->title,
            'company_name' => $template->company_name,
            'footer_remark_label' => $template->footer_remark_label,
            'footer_judgement_label' => $template->footer_judgement_label,
            'footer_judgement_options' => $template->footer_judgement_options,
            'is_active' => $template->is_active,
            'linked_item_ids' => $template->linked_item_ids,
            'linked_process_id' => $template->linked_process_id,
            'approval_lines' => $template->approvalLines->map(function ($l) {
                $userName = null;
                if ($l->user_id) {
                    $userName = User::where('id', $l->user_id)->value('name');
                }

                return [
                    'id' => $l->id,
                    'name' => $l->name,
                    'dept' => $l->dept,
                    'role' => $l->role,
                    'user_id' => $l->user_id,
                    'user_name' => $userName,
                ];
            })->toArray(),
            'basic_fields' => $template->basicFields->map(function ($f) {
                return [
                    'id' => $f->id,
                    'label' => $f->label,
                    'field_key' => $f->field_key,
                    'field_type' => $f->field_type,
                    'default_value' => $f->default_value,
                ];
            })->toArray(),
            'sections' => $template->sections->map(function ($s) {
                return [
                    'id' => $s->id,
                    'title' => $s->title,
                    'image_path' => $s->image_path,
                    'items' => $s->items->map(function ($i) {
                        $fv = $i->field_values ?? [];

                        return [
                            'id' => $i->id,
                            'category' => $fv['category'] ?? $i->category,
                            'item' => $fv['item'] ?? $i->item,
                            'standard' => $fv['standard'] ?? $i->standard,
                            'tolerance' => $fv['tolerance'] ?? $i->tolerance,
                            'standard_criteria' => $fv['standard_criteria'] ?? $i->standard_criteria,
                            'method' => $fv['method'] ?? $i->method,
                            'measurement_type' => $fv['measurement_type'] ?? $i->measurement_type,
                            'frequency_n' => $fv['frequency_n'] ?? $i->frequency_n,
                            'frequency_c' => $fv['frequency_c'] ?? $i->frequency_c,
                            'frequency' => $fv['frequency'] ?? $i->frequency,
                            'regulation' => $fv['regulation'] ?? $i->regulation,
                            'field_values' => $fv,
                        ];
                    })->toArray(),
                ];
            })->toArray(),
            'columns' => $template->columns->map(function ($c) {
                return [
                    'id' => $c->id,
                    'label' => $c->label,
                    'width' => $c->width,
                    'column_type' => $c->column_type,
                    'group_name' => $c->group_name,
                    'sub_labels' => $c->sub_labels,
                ];
            })->toArray(),
            'section_fields' => $template->sectionFields->map(function ($f) {
                return [
                    'id' => $f->id,
                    'field_key' => $f->field_key,
                    'label' => $f->label,
                    'field_type' => $f->field_type,
                    'options' => $f->options,
                    'width' => $f->width,
                    'is_required' => $f->is_required,
                ];
            })->toArray(),
            'template_links' => $this->buildTemplateLinks($template),
        ];
    }

    /**
     * template_links 데이터 빌드 (linked_item_ids 레거시 호환)
     */
    private function buildTemplateLinks(DocumentTemplate $template): array
    {
        // 신규 template_links가 있으면 그대로 사용
        if ($template->links->isNotEmpty()) {
            return $template->links->map(function ($l) {
                $values = $l->linkValues->map(function ($v) use ($l) {
                    $displayText = $this->resolveDisplayText($l->source_table, $v->linkable_id, $l->display_fields);

                    return [
                        'id' => $v->id,
                        'linkable_id' => $v->linkable_id,
                        'display_text' => $displayText,
                    ];
                })->toArray();

                return [
                    'id' => $l->id,
                    'link_key' => $l->link_key,
                    'label' => $l->label,
                    'link_type' => $l->link_type,
                    'source_table' => $l->source_table,
                    'search_params' => $l->search_params,
                    'display_fields' => $l->display_fields,
                    'is_required' => $l->is_required,
                    'values' => $values,
                ];
            })->toArray();
        }

        // 레거시: linked_item_ids만 있고 template_links가 없는 경우 가상 엔트리 생성
        $linkedItemIds = $template->linked_item_ids;
        if (! empty($linkedItemIds) && is_array($linkedItemIds)) {
            $displayFields = ['title' => 'name', 'subtitle' => 'code'];
            $values = collect($linkedItemIds)->map(function ($itemId) use ($displayFields) {
                return [
                    'id' => $itemId,
                    'linkable_id' => $itemId,
                    'display_text' => $this->resolveDisplayText('items', $itemId, $displayFields),
                ];
            })->toArray();

            return [[
                'id' => 'legacy',
                'link_key' => 'items',
                'label' => '연결 품목',
                'link_type' => 'multiple',
                'source_table' => 'items',
                'search_params' => null,
                'display_fields' => $displayFields,
                'is_required' => false,
                'values' => $values,
            ]];
        }

        return [];
    }

    /**
     * 소스 테이블에서 레코드의 표시 텍스트 조회
     */
    private function resolveDisplayText(?string $sourceTable, int $linkableId, ?array $displayFields): string
    {
        if (! $sourceTable || ! $linkableId) {
            return "ID: {$linkableId}";
        }

        $titleField = $displayFields['title'] ?? 'name';
        $subtitleField = $displayFields['subtitle'] ?? null;

        // 모델 매핑
        $modelMap = [
            'items' => \App\Models\Items\Item::class,
            'processes' => \App\Models\Process::class,
            'users' => \App\Models\User::class,
        ];

        try {
            if (isset($modelMap[$sourceTable])) {
                $record = $modelMap[$sourceTable]::find($linkableId);
            } else {
                $record = DB::table($sourceTable)->find($linkableId);
            }

            if (! $record) {
                return "ID: {$linkableId}";
            }

            $title = is_object($record) ? ($record->$titleField ?? '') : ($record->$titleField ?? '');
            $subtitle = $subtitleField ? (is_object($record) ? ($record->$subtitleField ?? '') : ($record->$subtitleField ?? '')) : '';

            return $title.($subtitle ? " ({$subtitle})" : '');
        } catch (\Exception $e) {
            return "ID: {$linkableId}";
        }
    }
}
