{{-- resources/views/admin/members/join_filters/index.blade.php --}}
@extends('admin.layouts.app')

@section('title', '회원가입 필터')
@section('page_title', '회원가입 필터')
@section('page_desc', '회원가입 IP 필터를 등록/수정/삭제합니다.')
@section('content_class', 'a-content--full')

@push('head')
    <style>
        .bar{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap;}
        .filters{display:flex;gap:8px;flex-wrap:wrap;align-items:flex-end;}
        .filters .sel{width:180px;}
        .filters .ip{width:240px;}

        .lbtn{padding:8px 12px;font-size:13px;border-radius:12px;line-height:1.1;text-decoration:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;
            border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.06);color:inherit;cursor:pointer;}
        .lbtn:hover{background:rgba(255,255,255,.10);text-decoration:none;}
        .lbtn--ghost{background:transparent;}
        .lbtn--sm{padding:7px 10px;font-size:12px;border-radius:11px;}
        .lbtn--primary{background:rgba(59,130,246,.88);border-color:rgba(59,130,246,.95);color:#fff;}
        .lbtn--primary:hover{background:rgba(59,130,246,.98);}
        .lbtn--danger{background:rgba(244,63,94,.88);border-color:rgba(244,63,94,.95);color:#fff;}
        .lbtn--danger:hover{background:rgba(244,63,94,.98);}

        .pill{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;font-size:12px;
            border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.06);}
        .pill--bad{border-color:rgba(244,63,94,.35);background:rgba(244,63,94,.10);}   /* A */
        .pill--warn{border-color:rgba(245,158,11,.35);background:rgba(245,158,11,.12);} /* S */
        .pill--muted{opacity:.9;}                                                      /* N */

        .mono{padding:4px 8px;border-radius:10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);
            font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:12px;display:inline-block;}

        .line_through{ text-decoration:line-through; color:#b7b7b7; opacity:.9; }

        /* modal */
        .mback{position:fixed;inset:0;display:none;align-items:center;justify-content:center;z-index:9999;
            background:rgba(0,0,0,.55);backdrop-filter:blur(2px);}
        .mback.is-open{display:flex;}
        .modalx{width:min(860px, 92vw);max-height:88vh;overflow:auto;border-radius:18px;
            border:1px solid rgba(255,255,255,.12);background:rgba(18,18,18,.96);box-shadow:0 20px 60px rgba(0,0,0,.45);}
        .modalx__head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;padding:16px 16px 10px;border-bottom:1px solid rgba(255,255,255,.10);}
        .modalx__title{font-weight:900;font-size:16px;}
        .modalx__desc{font-size:12px;opacity:.8;margin-top:4px;}
        .modalx__body{padding:16px;}
        .modalx__foot{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid rgba(255,255,255,.10);}

        .fgrid{display:grid;grid-template-columns:1fr;gap:12px;}
        @media (min-width: 860px){ .fgrid{grid-template-columns:1fr 1fr;} }

        .field{display:flex;flex-direction:column;gap:6px;}
        .field label{font-size:12px;opacity:.85;}
        .help{font-size:12px;opacity:.75;line-height:1.6;}
        .radios{display:flex;gap:14px;flex-wrap:wrap;align-items:center;padding:10px;border-radius:14px;border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.03);}
        .radios label{display:inline-flex;gap:8px;align-items:center;font-size:13px;opacity:.95;margin:0;}
        .warnbox{border:1px solid rgba(245,158,11,.35);background:rgba(245,158,11,.10);border-radius:16px;padding:12px;}
        .warnbox b{font-weight:900;}

        .adminGrid{display:grid;grid-template-columns:1fr;gap:10px;margin-top:6px;}
        @media (min-width: 860px){ .adminGrid{grid-template-columns:1fr 1fr;} }
        .adminItem{display:flex;gap:10px;align-items:center;padding:10px;border-radius:14px;border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.03);}
        .adminItem input[type=checkbox]{transform:scale(1.05);}
        .adminItem__txt{display:flex;flex-direction:column;gap:4px;min-width:0;}
        .adminItem__txt .t{font-weight:900;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
        .adminItem__txt .d{font-size:12px;opacity:.8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
    </style>
@endpush

@section('content')
    @php
        $gubunMap = $gubunCodeMap ?? [];
        $jbMap = $joinBlockCode ?? [];
        $jbStyle = $joinBlockStyle ?? ['S'=>'pill--warn','A'=>'pill--bad','N'=>'pill--muted'];

        $gSel = (string)($filters['gubun_code'] ?? '');
        $jSel = (string)($filters['join_block'] ?? '');
        $ip   = (string)($filters['filter_ip'] ?? '');

        // ✅ 중요: 절대 URL(https/http) 꼬임 방지용으로 relative route 사용
        $indexUrl  = route('admin.join-filters.index', [], false);
        $storeUrl  = route('admin.join-filters.store', [], false);
        $getTpl    = route('admin.join-filters.get', ['seq' => '__SEQ__'], false);
        $updateTpl = route('admin.join-filters.update', ['seq' => '__SEQ__'], false);

        // ✅ ParseError 방지: old payload는 PHP에서 먼저 만든다
        $oldPayload = [
            'filter_seq'  => old('filter_seq', ''),
            'gubun_code'  => old('gubun_code', '01'),
            'filter'      => old('filter', ''),
            'join_block'  => old('join_block', 'S'),
            'admin_phone' => old('admin_phone', []),
        ];
    @endphp

    <div class="a-card" style="padding:16px; margin-bottom:16px;">
        <div class="bar">
            <div>
                <div style="font-weight:900;font-size:16px;">회원가입 필터</div>
                <div class="a-muted" style="font-size:12px;margin-top:4px;">등록/수정은 모달에서 처리 · 수정은 AJAX로 row 로드</div>
            </div>

            <div style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;">
                <form method="GET" action="{{ $indexUrl }}" class="filters">
                    <div>
                        <select class="a-input sel" name="gubun_code">
                            <option value="">필터구분 전체</option>
                            <option value="02" {{ $gSel==='02'?'selected':'' }}>D-class</option>
                            <option value="01" {{ $gSel==='01'?'selected':'' }}>C-class</option>
                        </select>
                    </div>

                    <div>
                        <select class="a-input sel" name="join_block">
                            <option value="">가입차단여부 전체</option>
                            <option value="A" {{ $jSel==='A'?'selected':'' }}>회원가입차단</option>
                            <option value="S" {{ $jSel==='S'?'selected':'' }}>관리자SMS알림</option>
                            <option value="N" {{ $jSel==='N'?'selected':'' }}>필터끔</option>
                        </select>
                    </div>

                    <div>
                        <input class="a-input ip" name="filter_ip" value="{{ $ip }}" placeholder="아이피만 입력 (예: 192.168.0 / 192.168.0.1)">
                    </div>

                    <div style="display:flex;gap:8px;">
                        <button class="lbtn lbtn--ghost" type="submit">검색</button>
                        <a class="lbtn lbtn--ghost" href="{{ $indexUrl }}">초기화</a>
                    </div>
                </form>

                <button class="lbtn lbtn--primary" type="button" id="btnOpenCreate">+ 아이피차단 필터등록</button>
            </div>
        </div>
    </div>

    <div class="a-card" style="padding:16px;">
        <div class="a-muted" style="margin-bottom:10px;">총 <b>{{ $page->total() }}</b>건 (20개씩)</div>

        <div style="overflow:auto;">
            <table class="a-table table" style="width:100%; min-width:1100px;">
                <thead>
                <tr>
                    <th style="width:80px;">SEQ</th>
                    <th style="width:210px;">필터구분 [코드]</th>
                    <th style="width:220px;">필터내용</th>
                    <th style="width:220px;">가입차단여부</th>
                    <th>관리자전화번호</th>
                    <th style="width:120px;">등록자</th>
                    <th style="width:170px;">등록시간</th>
                    <th style="width:190px;">처리</th>
                </tr>
                </thead>

                <tbody>
                @forelse(($rows ?? []) as $r)
                    @php
                        $seq = (int)($r['seq'] ?? 0);
                        $jb  = (string)($r['join_block'] ?? 'N');
                        $phones = $r['admin_phone_arr'] ?? [];

                        $styleVal = $jbStyle[$jb] ?? 'pill--muted';
                        $styleCls = is_array($styleVal) ? (string)($styleVal['class'] ?? 'pill--muted') : (string)$styleVal;

                        $trCls = ($jb === 'N') ? 'line_through' : '';
                    @endphp
                    <tr class="{{ $trCls }}">
                        <td class="a-muted">{{ $seq }}</td>
                        <td>
                            {{ $r['gubun'] ?? '-' }}
                            <span class="a-muted">[{{ $r['gubun_code'] ?? '-' }}]</span>
                        </td>
                        <td><span class="mono">{{ $r['filter'] ?? '-' }}</span></td>
                        <td>
                            <span class="pill {{ $styleCls }}">
                                ● {{ $jbMap[$jb] ?? $jb }}
                            </span>
                        </td>
                        <td>
                            @php
                                $formatPhone = function ($v) {
                                    $s = trim((string)$v);
                                    if ($s === '' || $s === 'SMS발송없음') return '';

                                    $d = preg_replace('/\D+/', '', $s);

                                    // 11자리(010xxxxxxxx / 011xxxxxxxx 등)
                                    if (preg_match('/^\d{11}$/', $d)) {
                                        return substr($d,0,3).'-'.substr($d,3,4).'-'.substr($d,7,4);
                                    }

                                    // 10자리(구형 일부 케이스)
                                    if (preg_match('/^\d{10}$/', $d)) {
                                        return substr($d,0,3).'-'.substr($d,3,3).'-'.substr($d,6,4);
                                    }

                                    // 그 외는 원문 유지
                                    return $s;
                                };

                                $phonesLine = collect($phones ?? [])
                                    ->map($formatPhone)
                                    ->filter(fn($x) => $x !== '')
                                    ->implode(', ');
                            @endphp

                            @if($phonesLine === '')
                                <span class="a-muted">-</span>
                            @else
                                <span class="mono">{{ $phonesLine }}</span>
                            @endif
                        </td>
                        <td class="a-muted">{{ $r['admin'] ?? '-' }}</td>
                        <td class="a-muted">{{ $r['dt_reg'] ?? '-' }}</td>
                        <td style="display:flex;gap:8px;align-items:center;justify-content:flex-end;">
                            <button type="button"
                                    class="lbtn lbtn--ghost lbtn--sm btnEdit"
                                    data-seq="{{ $seq }}">
                                수정
                            </button>

                            <form method="POST" action="{{ route('admin.join-filters.destroy', ['seq'=>$seq], false) }}" style="display:inline;">
                                @csrf
                                <input type="hidden" name="_return_to" value="{{ request()->getRequestUri() }}">
                                <button class="lbtn lbtn--danger lbtn--sm" type="submit" onclick="return confirm('삭제할까요?');">삭제</button>
                            </form>
                        </td>
                    </tr>
                @empty
                    <tr><td colspan="8" class="a-muted" style="padding:16px;">데이터가 없습니다.</td></tr>
                @endforelse
                </tbody>
            </table>
        </div>

        <div style="margin-top:12px;">
            {{ $page->onEachSide(1)->links('vendor.pagination.admin') }}
        </div>
    </div>

    {{-- Modal --}}
    <div class="mback" id="joinFilterModalBack" aria-hidden="true">
        <div class="modalx" role="dialog" aria-modal="true" aria-labelledby="joinFilterModalTitle">
            <div class="modalx__head">
                <div>
                    <div class="modalx__title" id="joinFilterModalTitle">회원가입 알림/차단 아이피 등록</div>
                    <div class="modalx__desc" id="joinFilterModalDesc">C/D class 아이피 필터를 입력하고 처리방법을 선택하세요.</div>
                </div>
                <button class="lbtn lbtn--ghost lbtn--sm" type="button" id="btnCloseModal">닫기 ✕</button>
            </div>

            <form method="POST" id="joinFilterForm" action="{{ $storeUrl }}">
                @csrf
                <input type="hidden" name="_return_to" value="{{ request()->getRequestUri() }}">

                {{-- ✅ join_block != S 일 때 disabled된 체크값을 hidden으로 보강 제출 --}}
                <div id="adminPhoneHidden"></div>

                <div class="modalx__body">
                    <input type="hidden" name="filter_seq" id="filter_seq" value="">

                    {{-- ✅ 서버 에러가 있으면 모달 안에서 바로 보이게 --}}
                    @if($errors->any())
                        <div class="warnbox" style="margin-bottom:12px;">
                            <b>저장 실패</b><br>
                            <div style="margin-top:6px; font-size:12px; line-height:1.6;">
                                @foreach($errors->all() as $msg)
                                    <div>• {{ $msg }}</div>
                                @endforeach
                            </div>
                        </div>
                    @endif

                    <div class="fgrid">
                        <div class="field">
                            <label>필터구분</label>
                            <select class="a-input" name="gubun_code" id="gubun_code">
                                <option value="01">IP C class (192.168.0)</option>
                                <option value="02">IP D class (192.168.0.1)</option>
                            </select>
                            <div class="help">C-class: 3옥텟 / D-class: 4옥텟</div>
                        </div>

                        <div class="field">
                            <label>필터내용 (아이피만)</label>
                            <input class="a-input" type="text" name="filter" id="filter" placeholder="예: 192.168.0 또는 192.168.0.1">
                            <div class="help">숫자와 점(.)만 입력</div>
                        </div>
                    </div>

                    <div class="field" style="margin-top:12px;">
                        <label>처리방법</label>
                        <div class="radios" id="join_block_wrap">
                            <label><input type="radio" name="join_block" value="S"> <span class="pill pill--warn">● 관리자SMS알림</span></label>
                            <label><input type="radio" name="join_block" value="A"> <span class="pill pill--bad">● 회원가입차단</span></label>
                            <label><input type="radio" name="join_block" value="N"> <span class="pill pill--muted">● 필터끔</span></label>
                        </div>
                    </div>

                    <div class="field" style="margin-top:14px;">
                        <label>SMS로 알람받을 관리자 선택</label>
                        <div class="help">
                            - <b>관리자SMS알림</b>일 때만 선택/변경 가능합니다.<br>
                        </div>

                        <div class="adminGrid" id="adminGrid">
                            @foreach(($admins ?? []) as $a0)
                                @php
                                    $a = is_array($a0) ? $a0 : (array)$a0;

                                    $pname = (string)($a['name'] ?? '');
                                    $pemail = (string)($a['email'] ?? '');
                                    $plain = (string)($a['phone_plain'] ?? '');
                                    $plainDigits = preg_replace('/\D+/', '', $plain) ?: '';
                                    $pdisp = (string)($a['phone_display'] ?? '');
                                    $hasPhone = $plainDigits !== '';
                                @endphp

                                <label class="adminItem" style="{{ $hasPhone ? '' : 'opacity:.55;' }}">
                                    <input type="checkbox"
                                           name="admin_phone[]"
                                           value="{{ $plainDigits }}"
                                           data-orig-disabled="{{ $hasPhone ? '0' : '1' }}"
                                        {{ $hasPhone ? '' : 'disabled' }}>
                                    <div class="adminItem__txt">
                                        <div class="t">{{ $pname !== '' ? $pname : '-' }}</div>
                                        <div class="d">
                                            {{ $pdisp !== '' ? $pdisp : '전화번호 없음' }}
                                            @if($pemail !== '')
                                                <span class="a-muted"> · {{ $pemail }}</span>
                                            @endif
                                        </div>
                                    </div>
                                </label>
                            @endforeach
                        </div>

                        <div class="warnbox" style="margin-top:12px;">
                            <b>주의</b><br>
                            - 회원가입차단 선택 시 가입이 차단됩니다.<br>
                            - 필터끔은 리스트에 남기되 동작하지 않게 관리할 때 사용하세요.
                        </div>
                    </div>
                </div>

                <div class="modalx__foot">
                    <button class="lbtn lbtn--ghost" type="button" id="btnCancelModal">닫기</button>
                    <button class="lbtn lbtn--primary" type="submit" id="btnSubmitModal">저장하기</button>
                </div>
            </form>
        </div>
    </div>

    <script>
        (function(){
            const getTpl    = @json($getTpl);
            const updateTpl = @json($updateTpl);
            const storeUrl  = @json($storeUrl);

            const modalBack = document.getElementById('joinFilterModalBack');
            const btnOpenCreate = document.getElementById('btnOpenCreate');
            const btnClose = document.getElementById('btnCloseModal');
            const btnCancel = document.getElementById('btnCancelModal');

            const form = document.getElementById('joinFilterForm');
            const titleEl = document.getElementById('joinFilterModalTitle');
            const descEl = document.getElementById('joinFilterModalDesc');

            const seqEl = document.getElementById('filter_seq');
            const gubunEl = document.getElementById('gubun_code');
            const filterEl = document.getElementById('filter');

            const submitBtn = document.getElementById('btnSubmitModal');
            const hiddenBox = document.getElementById('adminPhoneHidden');

            const radios = Array.from(document.querySelectorAll('input[name="join_block"]'));
            const adminChecks = Array.from(document.querySelectorAll('#adminGrid input[type="checkbox"][name="admin_phone[]"]'));

            const digits = (s) => String(s || '').replace(/\D+/g, '');

            const openModal = () => {
                modalBack.classList.add('is-open');
                modalBack.setAttribute('aria-hidden', 'false');
                document.body.style.overflow = 'hidden';
            };
            const closeModal = () => {
                modalBack.classList.remove('is-open');
                modalBack.setAttribute('aria-hidden', 'true');
                document.body.style.overflow = '';
            };

            const currentJoinBlock = () => radios.find(r => r.checked)?.value || 'N';

            const syncHiddenPhones = () => {
                if (!hiddenBox) return;
                hiddenBox.innerHTML = '';

                const jb = currentJoinBlock();
                if (jb === 'S') return;

                adminChecks.forEach(chk => {
                    if (chk.getAttribute('data-orig-disabled') === '1') return;
                    if (!chk.checked) return;

                    const v = digits(chk.value);
                    if (!v) return;

                    const inp = document.createElement('input');
                    inp.type = 'hidden';
                    inp.name = 'admin_phone[]';
                    inp.value = v;
                    hiddenBox.appendChild(inp);
                });
            };

            const setAdminChecksEnabled = (enabled) => {
                adminChecks.forEach(chk => {
                    if (chk.getAttribute('data-orig-disabled') === '1') return;
                    chk.disabled = !enabled;
                });
                syncHiddenPhones();
            };

            const pickJoinBlock = (v) => {
                radios.forEach(r => r.checked = (r.value === v));
                setAdminChecksEnabled(v === 'S');
            };

            const clearAdminChecks = () => {
                adminChecks.forEach(chk => {
                    if (chk.getAttribute('data-orig-disabled') === '1') return;
                    chk.checked = false;
                });
                syncHiddenPhones();
            };

            const resetFormForCreate = () => {
                titleEl.textContent = '회원가입 알림/차단 아이피 등록';
                descEl.textContent = 'C/D class 아이피 필터를 입력하고 처리방법을 선택하세요.';
                form.action = storeUrl;
                seqEl.value = '';

                gubunEl.value = '01';
                filterEl.value = '';

                pickJoinBlock('S');
                clearAdminChecks();

                submitBtn.textContent = '등록';
                submitBtn.disabled = false;
            };

            const applyAdminChecksFromRow = (row) => {
                const arr = Array.isArray(row.admin_phone_arr) ? row.admin_phone_arr : [];
                const set = new Set(arr.map(v => digits(v)).filter(v => v));

                adminChecks.forEach(chk => {
                    if (chk.getAttribute('data-orig-disabled') === '1') return;
                    chk.checked = set.has(digits(chk.value));
                });

                syncHiddenPhones();
            };

            const fillFormForEdit = (row) => {
                const seq = row.seq ?? row.filter_seq ?? '';
                titleEl.textContent = `회원가입 필터 수정 #${seq}`;
                descEl.textContent = '수정 후 저장하기를 누르면 즉시 반영됩니다.';
                form.action = updateTpl.replace('__SEQ__', encodeURIComponent(seq));
                seqEl.value = String(seq);

                gubunEl.value = String(row.gubun_code ?? '01');
                filterEl.value = String(row.filter ?? '');

                const jb = String(row.join_block ?? 'N');
                pickJoinBlock(jb);

                applyAdminChecksFromRow(row);

                submitBtn.textContent = '저장';
                submitBtn.disabled = false;
            };

            // radio change
            radios.forEach(r => {
                r.addEventListener('change', () => {
                    const v = currentJoinBlock();
                    setAdminChecksEnabled(v === 'S');
                });
            });

            // open create
            btnOpenCreate?.addEventListener('click', () => {
                resetFormForCreate();
                openModal();
                setTimeout(() => filterEl?.focus(), 30);
            });

            // close
            btnClose?.addEventListener('click', closeModal);
            btnCancel?.addEventListener('click', closeModal);
            modalBack?.addEventListener('click', (e) => { if (e.target === modalBack) closeModal(); });
            document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modalBack.classList.contains('is-open')) closeModal(); });

            // submit
            form?.addEventListener('submit', () => {
                syncHiddenPhones();
                submitBtn.disabled = true;
            });

            // ✅ edit -> AJAX get
            Array.from(document.querySelectorAll('.btnEdit')).forEach(btn => {
                btn.addEventListener('click', async () => {
                    const seq = btn.getAttribute('data-seq');
                    if (!seq) return;

                    const url = getTpl.replace('__SEQ__', encodeURIComponent(seq));

                    try {
                        btn.disabled = true;

                        const res = await fetch(url, {
                            method: 'GET',
                            headers: {
                                'Accept': 'application/json',
                                'X-Requested-With': 'XMLHttpRequest',
                            },
                            credentials: 'same-origin',
                        });

                        if (res.status === 401 || res.status === 419) throw new Error('AUTH');
                        if (res.status === 403) throw new Error('FORBIDDEN');
                        if (!res.ok) throw new Error('HTTP_' + res.status);

                        const ct = (res.headers.get('content-type') || '').toLowerCase();
                        if (!ct.includes('application/json')) throw new Error('NOT_JSON');

                        const payload = await res.json();

                        // ✅ 컨트롤러 응답이 {ok,row} 인데 row를 직접 쓰던게 버그였음
                        const row = payload?.row ?? payload;
                        if (!row) throw new Error('NOT_FOUND');

                        // 방어: admin_phone_arr 없으면 admin_phone에서 복구
                        if (!Array.isArray(row.admin_phone_arr)) {
                            try {
                                const a = JSON.parse(row.admin_phone || '[]');
                                row.admin_phone_arr = Array.isArray(a) ? a : [];
                            } catch (e) {
                                row.admin_phone_arr = [];
                            }
                        }

                        fillFormForEdit(row);
                        openModal();
                        setTimeout(() => filterEl?.focus(), 30);

                    } catch (e) {
                        if (String(e.message) === 'AUTH') alert('세션이 만료되었습니다. 다시 로그인해 주세요.');
                        else if (String(e.message) === 'FORBIDDEN') alert('권한이 없습니다. (super_admin만 접근)');
                        else if (String(e.message) === 'NOT_JSON') alert('응답이 JSON이 아닙니다. (로그인 리다이렉트/APP_URL/프록시 가능)');
                        else alert('수정 정보를 불러오지 못했습니다.');
                    } finally {
                        btn.disabled = false;
                    }
                });
            });

            // default
            pickJoinBlock('S');

            // ✅ 서버 validation 에러가 있으면 모달 다시 열어서 입력값 복구
            const hasErrors  = @json($errors->any());
            const oldPayload = @js($oldPayload); // ✅ ParseError 방지 + JS 안전 변환

            if (hasErrors) {
                const seq = String(oldPayload.filter_seq || '');
                const row = {
                    seq: seq,
                    gubun_code: oldPayload.gubun_code,
                    filter: oldPayload.filter,
                    join_block: oldPayload.join_block,
                    admin_phone_arr: Array.isArray(oldPayload.admin_phone) ? oldPayload.admin_phone : [],
                };

                if (seq) fillFormForEdit(row);
                else {
                    resetFormForCreate();
                    gubunEl.value = String(oldPayload.gubun_code || '01');
                    filterEl.value = String(oldPayload.filter || '');
                    pickJoinBlock(String(oldPayload.join_block || 'S'));
                    applyAdminChecksFromRow(row);
                }

                openModal();
                setTimeout(() => filterEl?.focus(), 30);
            }
        })();
    </script>
@endsection
