@extends('layouts.app')

@section('title', $project->name)

@section('content')
<!-- 페이지 헤더 -->
<div class="flex justify-between items-start mb-6">
    <div class="flex items-center gap-4">
        <a href="{{ route('pm.projects.index') }}" class="text-gray-500 hover:text-gray-700">
            ← 프로젝트 목록
        </a>
        <div>
            <h1 class="text-2xl font-bold text-gray-800">{{ $project->name }}</h1>
            @if($project->description)
            <p class="text-gray-500 mt-1">{{ $project->description }}</p>
            @endif
        </div>
    </div>
    <div class="flex items-center gap-2">
        <span class="px-3 py-1.5 text-sm font-medium rounded-lg {{ $project->status_color }}">
            {{ $project->status_label }}
        </span>
        <a href="{{ route('pm.projects.edit', $project->id) }}"
           class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1.5 rounded-lg transition text-sm font-medium">
            수정
        </a>
    </div>
</div>

<!-- 프로젝트 통계 카드 -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
    <!-- 진행률 (2색상: 완료 + 진행중) -->
    <div class="bg-white rounded-lg shadow-sm p-4">
        <p class="text-sm text-gray-500 mb-2">진행률</p>
        <div class="flex items-center gap-3">
            <div class="flex-1 bg-gray-200 rounded-full h-3 relative overflow-hidden">
                <!-- 진행중 (파란색, 뒤에 깔림) -->
                <div id="progress-bar-inprogress" class="absolute h-3 rounded-full bg-blue-400 transition-all duration-300" style="width: 0%"></div>
                <!-- 완료 (녹색, 앞에 표시) -->
                <div id="progress-bar-done" class="absolute h-3 rounded-full bg-green-500 transition-all duration-300" style="width: 0%"></div>
            </div>
            <span id="progress-text" class="text-xl font-bold text-gray-800">0%</span>
        </div>
        <div class="flex gap-2 mt-1 text-xs text-gray-500">
            <span>완료 <span id="progress-done-pct" class="text-green-600 font-medium">0%</span></span>
            <span>+ 진행 <span id="progress-inprogress-pct" class="text-blue-600 font-medium">0%</span></span>
        </div>
    </div>

    <!-- 작업 현황 -->
    <div class="bg-white rounded-lg shadow-sm p-4">
        <p class="text-sm text-gray-500 mb-2">작업 현황</p>
        <div class="flex items-center gap-2">
            <span id="task-total" class="text-xl font-bold text-gray-800">0</span>
            <span class="text-sm text-gray-500">개</span>
        </div>
        <div class="flex gap-2 mt-2 text-xs">
            <span class="px-2 py-1 bg-gray-100 text-gray-600 rounded">할일 <span id="task-todo">0</span></span>
            <span class="px-2 py-1 bg-blue-100 text-blue-600 rounded">진행 <span id="task-inprogress">0</span></span>
            <span class="px-2 py-1 bg-green-100 text-green-600 rounded">완료 <span id="task-done">0</span></span>
        </div>
    </div>

    <!-- 이슈 현황 -->
    <div class="bg-white rounded-lg shadow-sm p-4">
        <p class="text-sm text-gray-500 mb-2">이슈 현황</p>
        <div class="flex items-center gap-2">
            <span id="issue-total" class="text-xl font-bold text-gray-800">0</span>
            <span class="text-sm text-gray-500">개</span>
        </div>
        <div class="flex gap-2 mt-2 text-xs">
            <span class="px-2 py-1 bg-red-100 text-red-600 rounded">열림 <span id="issue-open">0</span></span>
            <span class="px-2 py-1 bg-yellow-100 text-yellow-600 rounded">진행 <span id="issue-inprogress">0</span></span>
            <span class="px-2 py-1 bg-green-100 text-green-600 rounded">해결 <span id="issue-resolved">0</span></span>
        </div>
    </div>

    <!-- 기간 -->
    <div class="bg-white rounded-lg shadow-sm p-4">
        <p class="text-sm text-gray-500 mb-2">기간</p>
        @if($project->start_date || $project->end_date)
        <div class="text-sm text-gray-800">
            <p>시작: {{ $project->start_date?->format('Y-m-d') ?? '-' }}</p>
            <p>종료: {{ $project->end_date?->format('Y-m-d') ?? '-' }}</p>
        </div>
        @else
        <p class="text-gray-400">미설정</p>
        @endif
    </div>
</div>

<!-- 탭 영역 -->
<div class="bg-white rounded-lg shadow-sm">
    <!-- 탭 헤더 -->
    <div class="border-b border-gray-200">
        <nav class="flex -mb-px">
            <button onclick="switchTab('tasks')" id="tab-tasks"
                    class="tab-btn px-6 py-3 text-sm font-medium border-b-2 border-blue-500 text-blue-600">
                작업 ({{ $project->tasks_count ?? 0 }})
            </button>
            <button onclick="switchTab('issues')" id="tab-issues"
                    class="tab-btn px-6 py-3 text-sm font-medium border-b-2 border-transparent text-gray-500 hover:text-gray-700">
                이슈 ({{ $project->issues_count ?? 0 }})
            </button>
        </nav>
    </div>

    <!-- 탭 컨텐츠: 작업 -->
    <div id="content-tasks" class="tab-content">
        <!-- 작업 추가 버튼 -->
        <div class="p-4 border-b border-gray-200 flex justify-between items-center">
            <div class="flex gap-2 items-center">
                <select id="taskBulkAction" class="px-3 py-2 border border-gray-300 rounded-lg text-sm" onchange="handleTaskBulkAction()">
                    <option value="">일괄 작업</option>
                    <option value="change_status:todo">상태: 할일로 변경</option>
                    <option value="change_status:in_progress">상태: 진행중으로 변경</option>
                    <option value="change_status:done">상태: 완료로 변경</option>
                    <option value="change_priority:high">우선순위: 높음</option>
                    <option value="change_priority:medium">우선순위: 중간</option>
                    <option value="change_priority:low">우선순위: 낮음</option>
                    <option value="delete">삭제</option>
                </select>
            </div>
            <button onclick="openTaskModal()"
                    class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition text-sm">
                + 작업 추가
            </button>
        </div>

        <!-- 작업 목록 -->
         <div id="task-list" class="divide-y divide-gray-200">
            <div class="flex justify-center items-center p-12">
                <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
            </div>
        </div>
    </div>

    <!-- 탭 컨텐츠: 이슈 -->
    <div id="content-issues" class="tab-content hidden">
        <!-- 이슈 추가 버튼 -->
        <div class="p-4 border-b border-gray-200 flex justify-between items-center">
            <div class="flex gap-2 items-center">
                <select id="issueBulkAction" class="px-3 py-2 border border-gray-300 rounded-lg text-sm" onchange="handleIssueBulkAction()">
                    <option value="">일괄 작업</option>
                    <option value="change_status:open">상태: Open</option>
                    <option value="change_status:in_progress">상태: 진행중</option>
                    <option value="change_status:resolved">상태: 해결됨</option>
                    <option value="change_status:closed">상태: 종료</option>
                    <option value="change_type:bug">타입: 버그</option>
                    <option value="change_type:feature">타입: 기능</option>
                    <option value="change_type:improvement">타입: 개선</option>
                    <option value="delete">삭제</option>
                </select>
                <!-- 정렬 컨트롤 -->
                <div class="border-l border-gray-200 pl-3 ml-1" id="issue-sort-controls"></div>
            </div>
            <button onclick="openIssueModal()"
                    class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition text-sm">
                + 이슈 추가
            </button>
        </div>

        <!-- 이슈 목록 -->
        <div id="issue-list" class="divide-y divide-gray-200">
            <div class="flex justify-center items-center p-12">
                <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
            </div>
        </div>
    </div>
</div>

<!-- 작업 모달 -->
<div id="taskModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
    <div class="bg-white rounded-lg shadow-xl w-full max-w-lg mx-4">
        <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
            <h3 class="text-lg font-semibold" id="taskModalTitle">작업 추가</h3>
            <button onclick="closeTaskModal()" class="text-gray-400 hover:text-gray-600">✕</button>
        </div>
        <form id="taskForm" class="p-6">
            <input type="hidden" name="task_id" id="taskId">
            <input type="hidden" name="project_id" value="{{ $project->id }}">

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">제목 *</label>
                <input type="text" name="title" id="taskTitle" required
                       class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
            </div>

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">설명</label>
                <textarea name="description" id="taskDescription" rows="3"
                          class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"></textarea>
            </div>

            <div class="grid grid-cols-2 gap-4 mb-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">상태</label>
                    <select name="status" id="taskStatus"
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="todo">할일</option>
                        <option value="in_progress">진행중</option>
                        <option value="done">완료</option>
                    </select>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">우선순위</label>
                    <select name="priority" id="taskPriority"
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="low">낮음</option>
                        <option value="medium" selected>중간</option>
                        <option value="high">높음</option>
                    </select>
                </div>
            </div>

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">마감일</label>
                <input type="date" name="due_date" id="taskDueDate"
                       class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
            </div>

            <div class="flex justify-end gap-3">
                <button type="button" onclick="closeTaskModal()"
                        class="px-4 py-2 text-gray-600 hover:text-gray-800">취소</button>
                <button type="submit"
                        class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg">저장</button>
            </div>
        </form>
    </div>
</div>

<!-- 이슈 모달 -->
<div id="issueModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
    <div class="bg-white rounded-lg shadow-xl w-full max-w-lg mx-4">
        <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
            <h3 class="text-lg font-semibold" id="issueModalTitle">이슈 추가</h3>
            <button onclick="closeIssueModal()" class="text-gray-400 hover:text-gray-600">✕</button>
        </div>
        <form id="issueForm" class="p-6">
            <input type="hidden" name="issue_id" id="issueId">
            <input type="hidden" name="project_id" value="{{ $project->id }}">

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">제목 *</label>
                <input type="text" name="title" id="issueTitle" required
                       class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
            </div>

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">설명</label>
                <textarea name="description" id="issueDescription" rows="3"
                          class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"></textarea>
            </div>

            <div class="grid grid-cols-2 gap-4 mb-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">타입</label>
                    <select name="type" id="issueType"
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="bug">버그</option>
                        <option value="feature">기능</option>
                        <option value="improvement">개선</option>
                    </select>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">상태</label>
                    <select name="status" id="issueStatus"
                            class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                        <option value="open">Open</option>
                        <option value="in_progress">진행중</option>
                        <option value="resolved">해결됨</option>
                        <option value="closed">종료</option>
                    </select>
                </div>
            </div>

            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">연결된 작업</label>
                <select name="task_id" id="issueTaskId"
                        class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                    <option value="">없음</option>
                    @foreach($project->tasks as $task)
                    <option value="{{ $task->id }}">{{ $task->title }}</option>
                    @endforeach
                </select>
            </div>

            <div class="grid grid-cols-3 gap-4 mb-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">시작일</label>
                    <input type="date" name="start_date" id="issueStartDate"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">마감일</label>
                    <input type="date" name="due_date" id="issueDueDate"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">예상 시간</label>
                    <input type="number" name="estimated_hours" id="issueEstimatedHours" min="0" max="9999"
                           placeholder="시간"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
            </div>

            <!-- 팀/담당자/고객사 -->
            <div class="grid grid-cols-3 gap-4 mb-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">팀/부서</label>
                    <input type="text" name="team" id="issueTeam" placeholder="예: 개발팀"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">담당자</label>
                    <input type="text" name="assignee_name" id="issueAssigneeName" placeholder="예: 홍길동"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">고객사</label>
                    <input type="text" name="client" id="issueClient" placeholder="예: 경동기업"
                           class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500">
                </div>
            </div>

            <div class="flex justify-end gap-3">
                <button type="button" onclick="closeIssueModal()"
                        class="px-4 py-2 text-gray-600 hover:text-gray-800">취소</button>
                <button type="submit"
                        class="bg-red-600 hover:bg-red-700 text-white px-6 py-2 rounded-lg">저장</button>
            </div>
        </form>
    </div>
</div>
@endsection

@push('scripts')
<script>
    const projectId = {{ $project->id }};
    const csrfToken = '{{ csrf_token() }}';

    // 전역 데이터 저장 (대시보드 업데이트용)
    let tasksData = [];
    let issuesData = [];

    // 이슈 정렬 설정 (전역)
    const issueStatusPriority = { open: 0, in_progress: 1, resolved: 2, closed: 3 };
    const issueSortOptions = [
        { value: 'start_date', label: '시작일순', type: 'date', secondary: 'status' },
        { value: 'due_date', label: '마감일순', type: 'date' },
        { value: 'status', label: '상태순', type: 'priority', priority: issueStatusPriority },
        { value: 'client', label: '고객사별', type: 'group' },
        { value: 'team', label: '팀별', type: 'group' },
        { value: 'assignee_name', label: '담당자별', type: 'group' },
    ];

    // 현재 정렬 상태 (기본: 시작일)
    let currentIssueSort = 'start_date';
    let currentIssueSortDir = 'asc';

    // 작업 탭 아코디언 이슈 정렬 상태: null = 기본정렬, 'assignee' = 회사/팀/담당자, 'status' = 상태순
    let currentAccordionIssueSort = null;

    // 탭 전환
    function switchTab(tab) {
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.classList.remove('border-blue-500', 'text-blue-600');
            btn.classList.add('border-transparent', 'text-gray-500');
        });
        document.querySelectorAll('.tab-content').forEach(content => {
            content.classList.add('hidden');
        });

        document.getElementById(`tab-${tab}`).classList.add('border-blue-500', 'text-blue-600');
        document.getElementById(`tab-${tab}`).classList.remove('border-transparent', 'text-gray-500');
        document.getElementById(`content-${tab}`).classList.remove('hidden');
    }

    // 대시보드 업데이트
    function updateDashboard() {
        // 작업 통계
        const taskTotal = tasksData.length;
        const taskTodo = tasksData.filter(t => t.status === 'todo').length;
        const taskInProgress = tasksData.filter(t => t.status === 'in_progress').length;
        const taskDone = tasksData.filter(t => t.status === 'done').length;

        document.getElementById('task-total').textContent = taskTotal;
        document.getElementById('task-todo').textContent = taskTodo;
        document.getElementById('task-inprogress').textContent = taskInProgress;
        document.getElementById('task-done').textContent = taskDone;

        // 이슈 통계
        const issueTotal = issuesData.length;
        const issueOpen = issuesData.filter(i => i.status === 'open').length;
        const issueInProgress = issuesData.filter(i => i.status === 'in_progress').length;
        const issueResolved = issuesData.filter(i => i.status === 'resolved' || i.status === 'closed').length;

        document.getElementById('issue-total').textContent = issueTotal;
        document.getElementById('issue-open').textContent = issueOpen;
        document.getElementById('issue-inprogress').textContent = issueInProgress;
        document.getElementById('issue-resolved').textContent = issueResolved;

        // 진행률 계산 (2색상)
        if (taskTotal > 0) {
            const donePct = Math.round((taskDone / taskTotal) * 100);
            const inProgressPct = Math.round(((taskDone + taskInProgress) / taskTotal) * 100);

            document.getElementById('progress-bar-inprogress').style.width = inProgressPct + '%';
            document.getElementById('progress-bar-done').style.width = donePct + '%';
            document.getElementById('progress-text').textContent = inProgressPct + '%'; // 전체 진행률 표시
            document.getElementById('progress-done-pct').textContent = donePct + '%';
            document.getElementById('progress-inprogress-pct').textContent = (inProgressPct - donePct) + '%';
        } else {
            document.getElementById('progress-bar-inprogress').style.width = '0%';
            document.getElementById('progress-bar-done').style.width = '0%';
            document.getElementById('progress-text').textContent = '0%';
            document.getElementById('progress-done-pct').textContent = '0%';
            document.getElementById('progress-inprogress-pct').textContent = '0%';
        }

        // 탭 카운트 업데이트
        document.getElementById('tab-tasks').innerHTML = `작업 (${taskTotal})`;
        document.getElementById('tab-issues').innerHTML = `이슈 (${issueTotal})`;
    }

    // 작업 목록 로드
    async function loadTasks() {
        try {
            const response = await fetch(`/api/admin/pm/tasks/project/${projectId}`, {
                headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': csrfToken }
            });
            const result = await response.json();
            if (result.success) {
                tasksData = result.data;
                renderTasks(document.getElementById('task-list'), result.data);
                updateDashboard();
            }
        } catch (e) {
            console.error('Failed to load tasks:', e);
        }
    }

    // 이슈 목록 로드
    async function loadIssues() {
        try {
            const response = await fetch(`/api/admin/pm/issues/project/${projectId}`, {
                headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': csrfToken }
            });
            const result = await response.json();
            if (result.success) {
                issuesData = result.data;
                renderIssues(document.getElementById('issue-list'), result.data);
                updateDashboard();
            }
        } catch (e) {
            console.error('Failed to load issues:', e);
        }
    }

    // 페이지 로드 시 데이터 로드
    document.addEventListener('DOMContentLoaded', function() {
        initSortControls();
        loadTasks();
        loadIssues();
    });

    // 정렬 컨트롤 초기화
    function initSortControls() {
        // 이슈 탭 정렬 컨트롤
        const issueControls = document.getElementById('issue-sort-controls');
        if (issueControls) {
            issueControls.innerHTML = renderSortControl('issue', issueSortOptions, currentIssueSort, currentIssueSortDir);
            bindSortEvents('issue', (sort, dir) => {
                currentIssueSort = sort;
                currentIssueSortDir = dir;
                renderIssues(document.getElementById('issue-list'), issuesData);
            });
        }

        // 작업 탭 아코디언 이슈 정렬 컨트롤
        const accordionControls = document.getElementById('accordion-issue-sort-controls');
        if (accordionControls) {
            accordionControls.innerHTML = renderSortControl('accordion-issue', issueSortOptions, currentAccordionIssueSort, currentAccordionIssueSortDir);
            bindSortEvents('accordion-issue', (sort, dir) => {
                currentAccordionIssueSort = sort;
                currentAccordionIssueSortDir = dir;
                renderTasks(document.getElementById('task-list'), tasksData);
            });
        }
    }

    // 정렬 컨트롤 HTML 생성
    function renderSortControl(prefix, options, currentSort, currentDir) {
        return `
            <div class="flex items-center gap-2">
                <span class="text-xs text-gray-500">이슈 정렬:</span>
                <select id="${prefix}-sort"
                        class="text-xs px-2 py-1 border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
                    ${options.map(opt =>
                        `<option value="${opt.value}" ${currentSort === opt.value ? 'selected' : ''}>${opt.label}</option>`
                    ).join('')}
                </select>
                <button id="${prefix}-sort-dir"
                        class="p-1 text-gray-400 hover:text-gray-600 rounded hover:bg-gray-100 transition"
                        title="정렬 방향 변경">
                    <svg class="w-4 h-4 transition-transform ${currentDir === 'desc' ? 'rotate-180' : ''}"
                         fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/>
                    </svg>
                </button>
            </div>
        `;
    }

    // 정렬 이벤트 바인딩
    function bindSortEvents(prefix, callback) {
        const select = document.getElementById(`${prefix}-sort`);
        const dirBtn = document.getElementById(`${prefix}-sort-dir`);
        let currentDir = select?.closest('.flex')?.querySelector('button svg')?.classList.contains('rotate-180') ? 'desc' : 'asc';

        select?.addEventListener('change', (e) => {
            callback(e.target.value, currentDir);
        });

        dirBtn?.addEventListener('click', () => {
            currentDir = currentDir === 'asc' ? 'desc' : 'asc';
            dirBtn.querySelector('svg').classList.toggle('rotate-180');
            callback(select.value, currentDir);
        });
    }

    // 날짜 포맷 함수 (YYYY-MM-DD)
    function formatDate(dateStr) {
        if (!dateStr) return '';
        const date = new Date(dateStr);
        return date.toISOString().split('T')[0];
    }

    // 우선순위 SVG 아이콘
    const prioritySvg = {
        low: '<svg class="w-3 h-3 text-gray-400" fill="currentColor" viewBox="0 0 16 16"><path d="M8 12a4 4 0 100-8 4 4 0 000 8z"/></svg>',
        medium: '<svg class="w-3 h-3 text-yellow-500" fill="currentColor" viewBox="0 0 16 16"><path d="M8 12a4 4 0 100-8 4 4 0 000 8z"/></svg>',
        high: '<svg class="w-3 h-3 text-red-500" fill="currentColor" viewBox="0 0 16 16"><path d="M8 12a4 4 0 100-8 4 4 0 000 8z"/></svg>'
    };
    const priorityLabels = { low: '낮음', medium: '보통', high: '높음' };

    // 열린 아코디언 상태 저장
    const openAccordions = new Set();

    // 아코디언 토글
    function toggleTaskIssues(taskId) {
        const issueRows = document.querySelectorAll(`.task-issues-${taskId}`);
        const icon = document.getElementById(`toggle-icon-${taskId}`);
        const isCurrentlyHidden = issueRows[0]?.classList.contains('hidden');

        issueRows.forEach(row => row.classList.toggle('hidden'));
        if (icon) {
            icon.classList.toggle('rotate-90');
        }

        // 상태 저장
        if (isCurrentlyHidden) {
            openAccordions.add(taskId);
        } else {
            openAccordions.delete(taskId);
        }
    }

    // 작업 목록 렌더링 (테이블 형식 + 아코디언)
    function renderTasks(container, tasks) {
        if (!tasks || tasks.length === 0) {
            container.innerHTML = '<div class="py-6 text-center text-gray-500 text-sm">등록된 작업이 없습니다.</div>';
            return;
        }

        const statusColors = {
            todo: 'bg-gray-100 text-gray-600',
            in_progress: 'bg-blue-100 text-blue-600',
            done: 'bg-green-100 text-green-600'
        };
        const statusLabels = { todo: '할일', in_progress: '진행중', done: '완료' };
        const issueTypeLabels = { bug: '버그', feature: '기능', improvement: '개선' };
        const issueStatusColors = {
            open: 'bg-red-100 text-red-600',
            in_progress: 'bg-yellow-100 text-yellow-600',
            resolved: 'bg-green-100 text-green-600',
            closed: 'bg-gray-100 text-gray-600'
        };
        const issueStatusLabels = { open: '열림', in_progress: '진행중', resolved: '해결됨', closed: '종료' };

        // 프로젝트 기간 계산 (타임라인 기준)
        const projectStart = new Date('{{ $project->start_date?->format("Y-m-d") ?? now()->format("Y-m-d") }}');
        const projectEnd = new Date('{{ $project->end_date?->format("Y-m-d") ?? now()->addMonths(3)->format("Y-m-d") }}');
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const projectDuration = Math.max(1, (projectEnd - projectStart) / (1000 * 60 * 60 * 24));
        const todayPosition = Math.min(100, Math.max(0, ((today - projectStart) / (1000 * 60 * 60 * 24)) / projectDuration * 100));

        // 짧은 날짜 포맷 (MM/DD)
        const shortDate = (d) => d ? `${(d.getMonth()+1).toString().padStart(2,'0')}/${d.getDate().toString().padStart(2,'0')}` : '';

        // 테이블 헤더
        let html = `
        <table class="w-full text-sm">
            <colgroup>
                <col style="width: 32px;">
                <col style="width: 40px;">
                <col style="width: 180px;">
                <col>
                <col style="width: 64px;">
                <col style="width: 120px;">
                <col style="width: 80px;">
            </colgroup>
            <thead class="bg-gray-50 text-xs text-gray-500 uppercase">
                <tr>
                    <th class="px-2 py-2"></th>
                    <th class="px-1 py-2 text-center font-medium">긴급</th>
                    <th class="px-2 py-2 text-left font-medium">작업명</th>
                    <th class="px-2 py-2 text-left font-medium">타임라인</th>
                    <th class="px-2 py-2 text-center font-medium cursor-pointer hover:bg-gray-100 select-none" onclick="toggleAccordionIssueSort('assignee')" title="클릭: 회사/팀/담당자 정렬">
                        <span class="inline-flex items-center gap-1">이슈<span id="sort-icon-assignee" class="text-gray-400"></span></span>
                    </th>
                    <th class="px-2 py-2 text-center font-medium cursor-pointer hover:bg-gray-100 select-none" onclick="toggleAccordionIssueSort('status')" title="클릭: 상태순 정렬">
                        <span class="inline-flex items-center gap-1">상태<span id="sort-icon-status" class="text-gray-400"></span></span>
                    </th>
                    <th class="px-2 py-2 text-center font-medium">관리</th>
                </tr>
            </thead>
            <tbody>`;

        tasks.forEach(task => {
            const issueTotal = task.issues_count || 0;
            const issueResolved = task.resolved_issues_count || 0;
            const issueProgress = issueTotal > 0 ? Math.round((issueResolved / issueTotal) * 100) : 0;
            const issues = sortIssues(task.issues || []);
            const hasIssues = issues.length > 0;

            // Task 타임라인 계산 (이슈들의 min(start_date) ~ max(due_date))
            let taskStartDate = null;
            let taskEndDate = task.due_date ? new Date(task.due_date) : null;

            if (hasIssues) {
                issues.forEach(issue => {
                    if (issue.start_date) {
                        const issueStart = new Date(issue.start_date);
                        if (!taskStartDate || issueStart < taskStartDate) taskStartDate = issueStart;
                    }
                    if (issue.due_date) {
                        const issueEnd = new Date(issue.due_date);
                        if (!taskEndDate || issueEnd > taskEndDate) taskEndDate = issueEnd;
                    }
                });
            }

            // 타임라인 바 위치/너비 계산
            let timelineHtml = '';
            const isOverdue = taskEndDate && taskEndDate < today && task.status !== 'done';

            if (taskStartDate || taskEndDate) {
                const barStart = taskStartDate ? Math.max(0, Math.min(100, ((taskStartDate - projectStart) / (1000 * 60 * 60 * 24)) / projectDuration * 100)) :
                                 (taskEndDate ? Math.max(0, Math.min(100, ((taskEndDate - projectStart) / (1000 * 60 * 60 * 24)) / projectDuration * 100)) : 0);
                const barEnd = taskEndDate ? Math.max(0, Math.min(100, ((taskEndDate - projectStart) / (1000 * 60 * 60 * 24)) / projectDuration * 100)) : barStart;
                const barWidth = Math.max(2, barEnd - barStart);

                // 상태별 색상 (더 진하게)
                const barColor = task.status === 'done' ? 'bg-green-600' :
                                 task.status === 'in_progress' ? 'bg-blue-600' :
                                 isOverdue ? 'bg-red-500' : 'bg-gray-500';

                // 시작일/마감일 없이 포인트만 표시하는 경우
                const isPoint = !taskStartDate || barWidth < 5;

                // Task 날짜 레이블
                const taskDateLabel = taskStartDate && taskEndDate ? `${shortDate(taskStartDate)}~${shortDate(taskEndDate)}` :
                                      taskEndDate ? shortDate(taskEndDate) : shortDate(taskStartDate);

                timelineHtml = `
                    <div class="relative h-7 bg-gray-100 rounded overflow-hidden">
                        <!-- 오늘 표시선 -->
                        <div class="absolute top-0 bottom-0 w-0.5 bg-red-500 z-10" style="left: ${todayPosition}%;" title="오늘"></div>
                        <!-- 타임라인 바 -->
                        ${isPoint ?
                            `<div class="absolute top-1/2 -translate-y-1/2 w-3 h-3 rounded-full ${barColor} shadow-sm" style="left: calc(${barStart}% - 6px);" title="${taskDateLabel}"></div>` :
                            `<div class="absolute top-1 bottom-1 rounded ${barColor} flex items-center overflow-hidden shadow-sm" style="left: ${barStart}%; width: ${barWidth}%;">
                                <span class="text-[11px] text-white font-semibold whitespace-nowrap px-1.5 truncate w-full text-center drop-shadow-md">${taskDateLabel}</span>
                            </div>`
                        }
                    </div>`;
            } else {
                timelineHtml = `
                    <div class="relative h-7 bg-gray-100 rounded overflow-hidden">
                        <div class="absolute top-0 bottom-0 w-0.5 bg-red-500 z-10" style="left: ${todayPosition}%;" title="오늘"></div>
                        <span class="absolute inset-0 flex items-center justify-center text-xs text-gray-400">-</span>
                    </div>`;
            }

            // 작업 Row
            html += `
            <tr class="hover:bg-gray-50 border-b border-gray-100 ${hasIssues ? 'cursor-pointer' : ''}" ${hasIssues ? `onclick="toggleTaskIssues(${task.id})"` : ''}>
                <td class="px-2 py-1.5 text-center" onclick="event.stopPropagation()">
                    <input type="checkbox" class="task-checkbox w-4 h-4 rounded border-gray-300" data-id="${task.id}">
                </td>
                <td class="px-1 py-1.5 text-center" onclick="event.stopPropagation()">
                    <button onclick="toggleTaskUrgent(${task.id})" class="w-6 h-6 flex items-center justify-center rounded hover:bg-gray-100 transition ${task.is_urgent ? 'text-red-500' : 'text-gray-300 hover:text-gray-400'}" title="${task.is_urgent ? '긴급 해제' : '긴급 설정'}">
                        <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M12.395 2.553a1 1 0 00-1.45-.385c-.345.23-.614.558-.822.88-.214.33-.403.713-.57 1.116-.334.804-.614 1.768-.84 2.734a31.365 31.365 0 00-.613 3.58 2.64 2.64 0 01-.945-1.067c-.328-.68-.398-1.534-.398-2.654A1 1 0 005.05 6.05 6.981 6.981 0 003 11a7 7 0 1011.95-4.95c-.592-.591-.98-.985-1.348-1.467-.363-.476-.724-1.063-1.207-2.03zM12.12 15.12A3 3 0 017 13s.879.5 2.5.5c0-1 .5-4 1.25-4.5.5 1 .786 1.293 1.371 1.879A2.99 2.99 0 0113 13a2.99 2.99 0 01-.879 2.121z" clip-rule="evenodd"/></svg>
                    </button>
                </td>
                <td class="px-2 py-1.5">
                    <div class="flex items-center gap-1.5">
                        ${hasIssues ? `<svg id="toggle-icon-${task.id}" class="w-4 h-4 text-gray-400 transition-transform flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>` : '<span class="w-4 flex-shrink-0"></span>'}
                        <span title="우선순위: ${priorityLabels[task.priority]}" class="flex-shrink-0">${prioritySvg[task.priority]}</span>
                        <span class="font-medium text-gray-800 truncate ${task.is_urgent ? 'text-red-600' : ''}" title="${task.title}">${task.title}</span>
                    </div>
                </td>
                <td class="px-2 py-1.5">
                    ${timelineHtml}
                </td>
                <td class="px-2 py-1.5 text-center">
                    ${issueTotal > 0 ? `
                        <span class="inline-flex items-center gap-1 text-xs text-gray-600">
                            <span class="inline-block w-8 h-1.5 bg-gray-200 rounded-full overflow-hidden">
                                <span class="block h-full ${issueProgress === 100 ? 'bg-green-500' : 'bg-blue-500'}" style="width: ${issueProgress}%"></span>
                            </span>
                            <span>${issueResolved}/${issueTotal}</span>
                        </span>
                    ` : '<span class="text-xs text-gray-400">-</span>'}
                </td>
                <td class="px-2 py-1.5 text-center" onclick="event.stopPropagation()">
                    <div class="flex justify-center gap-0.5">
                        <button onclick="changeTaskStatus(${task.id}, 'todo')" class="px-1.5 py-0.5 text-xs rounded ${task.status === 'todo' ? 'bg-gray-500 text-white' : 'text-gray-400 hover:bg-gray-200'}" title="할일">할일</button>
                        <button onclick="changeTaskStatus(${task.id}, 'in_progress')" class="px-1.5 py-0.5 text-xs rounded ${task.status === 'in_progress' ? 'bg-blue-500 text-white' : 'text-gray-400 hover:bg-gray-200'}" title="진행중">진행</button>
                        <button onclick="changeTaskStatus(${task.id}, 'done')" class="px-1.5 py-0.5 text-xs rounded ${task.status === 'done' ? 'bg-green-500 text-white' : 'text-gray-400 hover:bg-gray-200'}" title="완료">완료</button>
                    </div>
                </td>
                <td class="px-2 py-1.5 text-center" onclick="event.stopPropagation()">
                    <div class="flex justify-center gap-1">
                        <button onclick="openIssueModalForTask(${task.id})" class="text-gray-400 hover:text-green-600" title="이슈 추가">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/></svg>
                        </button>
                        <button onclick="editTask(${task.id})" class="text-gray-400 hover:text-blue-600" title="작업 수정">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
                        </button>
                        <button onclick="deleteTask(${task.id})" class="text-gray-400 hover:text-red-600" title="작업 삭제">
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
                        </button>
                    </div>
                </td>
            </tr>`;

            // Task 기준 타임라인 범위 계산 (이슈들의 범위)
            const taskTimelineStart = taskStartDate || taskEndDate || today;
            const taskTimelineEnd = taskEndDate || taskStartDate || today;
            const taskDuration = Math.max(1, (taskTimelineEnd - taskTimelineStart) / (1000 * 60 * 60 * 24));
            const taskTodayPos = ((today - taskTimelineStart) / (1000 * 60 * 60 * 24)) / taskDuration * 100;
            const showTodayLine = taskTodayPos >= 0 && taskTodayPos <= 100; // 오늘이 범위 내인지

            // 이슈 서브 Rows (아코디언) - 7컬럼에 맞춤: 체크박스, 긴급, 이슈명, 타임라인, 담당, 상태버튼, 관리
            issues.forEach(issue => {
                // 이슈 타임라인 계산 (Task 기준)
                const issueStart = issue.start_date ? new Date(issue.start_date) : null;
                const issueEnd = issue.due_date ? new Date(issue.due_date) : null;
                const issueOverdue = issueEnd && issueEnd < today && issue.status !== 'resolved' && issue.status !== 'closed';

                let issueTimelineHtml = '';
                if ((issueStart || issueEnd) && taskStartDate) {
                    const iBarStart = issueStart ? Math.max(0, Math.min(100, ((issueStart - taskTimelineStart) / (1000 * 60 * 60 * 24)) / taskDuration * 100)) :
                                     (issueEnd ? Math.max(0, Math.min(100, ((issueEnd - taskTimelineStart) / (1000 * 60 * 60 * 24)) / taskDuration * 100)) : 0);
                    const iBarEnd = issueEnd ? Math.max(0, Math.min(100, ((issueEnd - taskTimelineStart) / (1000 * 60 * 60 * 24)) / taskDuration * 100)) : iBarStart;
                    const iBarWidth = Math.max(5, iBarEnd - iBarStart);

                    // 이슈 상태별 색상
                    const iBarColor = issue.status === 'resolved' || issue.status === 'closed' ? 'bg-green-400' :
                                      issue.status === 'in_progress' ? 'bg-yellow-400' :
                                      issueOverdue ? 'bg-red-300' : 'bg-blue-200';

                    const isIssuePoint = !issueStart || iBarWidth < 5;
                    const dateLabel = issueStart && issueEnd ? `${shortDate(issueStart)}~${shortDate(issueEnd)}` :
                                      issueEnd ? shortDate(issueEnd) : shortDate(issueStart);

                    issueTimelineHtml = `
                        <div class="relative h-5 bg-gray-50 rounded overflow-hidden">
                            ${showTodayLine ? `<div class="absolute top-0 bottom-0 w-0.5 bg-red-400 z-10" style="left: ${taskTodayPos}%;" title="오늘"></div>` : ''}
                            ${isIssuePoint ?
                                `<div class="absolute top-1/2 -translate-y-1/2 w-2 h-2 rounded-full ${iBarColor}" style="left: calc(${iBarStart}% - 4px);" title="${dateLabel}"></div>` :
                                `<div class="absolute top-0.5 bottom-0.5 rounded ${iBarColor} flex items-center overflow-hidden" style="left: ${iBarStart}%; width: ${iBarWidth}%;">
                                    <span class="text-[10px] text-white font-medium whitespace-nowrap px-1 truncate w-full text-center drop-shadow-sm">${dateLabel}</span>
                                </div>`
                            }
                        </div>`;
                } else {
                    issueTimelineHtml = `
                        <div class="relative h-5 bg-gray-50 rounded overflow-hidden">
                            <span class="absolute inset-0 flex items-center justify-center text-xs text-gray-300">-</span>
                        </div>`;
                }

                html += `
                <tr class="task-issues-${task.id} hidden bg-blue-50/30 border-b border-gray-100">
                    <td class="py-1"></td>
                    <td class="py-1 text-center" onclick="event.stopPropagation()">
                        <button onclick="toggleSubIssueUrgent(${issue.id}, ${task.id})" class="w-5 h-5 flex items-center justify-center rounded hover:bg-gray-100 transition ${issue.is_urgent ? 'text-red-500' : 'text-gray-300 hover:text-gray-400'}" title="${issue.is_urgent ? '긴급 해제' : '긴급 설정'}">
                            <svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M12.395 2.553a1 1 0 00-1.45-.385c-.345.23-.614.558-.822.88-.214.33-.403.713-.57 1.116-.334.804-.614 1.768-.84 2.734a31.365 31.365 0 00-.613 3.58 2.64 2.64 0 01-.945-1.067c-.328-.68-.398-1.534-.398-2.654A1 1 0 005.05 6.05 6.981 6.981 0 003 11a7 7 0 1011.95-4.95c-.592-.591-.98-.985-1.348-1.467-.363-.476-.724-1.063-1.207-2.03zM12.12 15.12A3 3 0 017 13s.879.5 2.5.5c0-1 .5-4 1.25-4.5.5 1 .786 1.293 1.371 1.879A2.99 2.99 0 0113 13a2.99 2.99 0 01-.879 2.121z" clip-rule="evenodd"/></svg>
                        </button>
                    </td>
                    <td class="py-1 pl-4">
                        <div class="flex items-center gap-2 border-l-2 border-blue-300 pl-3">
                            <span class="text-xs px-1.5 py-0.5 bg-gray-100 text-gray-500 rounded flex-shrink-0">${issueTypeLabels[issue.type] || issue.type}</span>
                            <span class="text-sm truncate ${issue.is_urgent ? 'text-red-600' : 'text-gray-700'}" title="${issue.title}">${issue.title}</span>
                        </div>
                    </td>
                    <td class="py-1 px-2">
                        ${issueTimelineHtml}
                    </td>
                    <td class="py-1 text-center text-xs text-gray-500 truncate" title="${[issue.client, issue.team, issue.assignee_name].filter(Boolean).join(' · ')}">
                        ${[issue.team, issue.assignee_name].filter(Boolean).join(' · ') || '-'}
                    </td>
                    <td class="py-1 text-center whitespace-nowrap" onclick="event.stopPropagation()">
                        <div class="inline-flex gap-px">
                            <button onclick="changeSubIssueStatus(${issue.id}, 'open', ${task.id})" class="px-1 py-0.5 text-xs rounded ${issue.status === 'open' ? 'bg-red-100 text-red-600' : 'text-gray-400 hover:bg-gray-200'}" title="열림">열림</button>
                            <button onclick="changeSubIssueStatus(${issue.id}, 'in_progress', ${task.id})" class="px-1 py-0.5 text-xs rounded ${issue.status === 'in_progress' ? 'bg-yellow-500 text-white' : 'text-gray-400 hover:bg-gray-200'}" title="진행">진행</button>
                            <button onclick="changeSubIssueStatus(${issue.id}, 'resolved', ${task.id})" class="px-1 py-0.5 text-xs rounded ${issue.status === 'resolved' ? 'bg-green-500 text-white' : 'text-gray-400 hover:bg-gray-200'}" title="해결">해결</button>
                        </div>
                    </td>
                    <td class="py-1 text-center" onclick="event.stopPropagation()">
                        <div class="flex justify-center gap-1">
                            <button onclick="editIssue(${issue.id})" class="text-gray-400 hover:text-blue-600" title="이슈 수정">
                                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
                            </button>
                            <button onclick="deleteIssue(${issue.id}, ${task.id})" class="text-gray-400 hover:text-red-600" title="이슈 삭제">
                                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
                            </button>
                        </div>
                    </td>
                </tr>`;
            });
        });

        html += '</tbody></table>';
        container.innerHTML = html;

        // 진행중 작업의 아코디언 자동 열기 (최초 로드시만)
        if (openAccordions.size === 0) {
            tasks.forEach(task => {
                if (task.status === 'in_progress' && task.issues && task.issues.length > 0) {
                    openAccordions.add(task.id);
                }
            });
        }

        // 열린 아코디언 상태 복원
        openAccordions.forEach(taskId => {
            const issueRows = document.querySelectorAll(`.task-issues-${taskId}`);
            const icon = document.getElementById(`toggle-icon-${taskId}`);
            issueRows.forEach(row => row.classList.remove('hidden'));
            if (icon) {
                icon.classList.add('rotate-90');
            }
        });
    }

    // 작업 탭 아코디언 이슈 정렬 토글 (헤더 클릭)
    function toggleAccordionIssueSort(sortType) {
        // 같은 헤더 클릭 시 기본정렬로 리셋
        if (currentAccordionIssueSort === sortType) {
            currentAccordionIssueSort = null;
        } else {
            currentAccordionIssueSort = sortType;
        }

        // 아이콘 업데이트
        updateSortIcons();

        // 목록 다시 렌더링
        renderTasks(document.getElementById('task-list'), tasksData);
    }

    // 정렬 아이콘 업데이트
    function updateSortIcons() {
        const assigneeIcon = document.getElementById('sort-icon-assignee');
        const statusIcon = document.getElementById('sort-icon-status');

        if (assigneeIcon) {
            assigneeIcon.textContent = currentAccordionIssueSort === 'assignee' ? '▼' : '';
        }
        if (statusIcon) {
            statusIcon.textContent = currentAccordionIssueSort === 'status' ? '▼' : '';
        }
    }

    // 이슈 정렬 함수
    function sortIssues(issues, sortField = null, sortDir = null) {
        if (!issues || issues.length === 0) return issues;

        // 아코디언(작업탭)에서 호출 시 currentAccordionIssueSort 사용
        const sortType = sortField || currentAccordionIssueSort;

        // 회사/팀/담당자 정렬 (assignee)
        if (sortType === 'assignee') {
            return [...issues].sort((a, b) => {
                // client(회사) → team(팀) → assignee_name(담당자) 순서로 정렬
                const clientA = (a.client || '').toLowerCase();
                const clientB = (b.client || '').toLowerCase();
                if (clientA !== clientB) return clientA.localeCompare(clientB, 'ko');

                const teamA = (a.team || '').toLowerCase();
                const teamB = (b.team || '').toLowerCase();
                if (teamA !== teamB) return teamA.localeCompare(teamB, 'ko');

                const assigneeA = (a.assignee_name || '').toLowerCase();
                const assigneeB = (b.assignee_name || '').toLowerCase();
                return assigneeA.localeCompare(assigneeB, 'ko');
            });
        }

        // 상태순 정렬 (status)
        if (sortType === 'status') {
            return [...issues].sort((a, b) => {
                return (issueStatusPriority[a.status] || 99) - (issueStatusPriority[b.status] || 99);
            });
        }

        // 이슈탭 드롭다운 정렬
        if (sortField && issueSortOptions.find(o => o.value === sortField)) {
            const dir = sortDir || 'asc';
            const option = issueSortOptions.find(o => o.value === sortField);

            if (typeof SortUtils !== 'undefined' && SortUtils.multiSort) {
                return SortUtils.multiSort(issues, [
                    { field: option.value, direction: dir, type: option.type, priority: option.priority },
                    ...(option.secondary ? [{ field: option.secondary, direction: 'asc', type: 'priority', priority: issueStatusPriority }] : [])
                ]);
            }
        }

        // 기본 정렬: 시작일 → 상태
        return [...issues].sort((a, b) => {
            if (a.start_date && b.start_date) {
                const diff = new Date(a.start_date) - new Date(b.start_date);
                if (diff !== 0) return diff;
            } else if (a.start_date && !b.start_date) {
                return -1;
            } else if (!a.start_date && b.start_date) {
                return 1;
            }
            return (issueStatusPriority[a.status] || 99) - (issueStatusPriority[b.status] || 99);
        });
    }

    // 이슈 목록 렌더링 (테이블 형식)
    function renderIssues(container, issues) {
        if (!issues || issues.length === 0) {
            container.innerHTML = '<div class="py-6 text-center text-gray-500 text-sm">등록된 이슈가 없습니다.</div>';
            return;
        }

        // 현재 이슈 탭 정렬 설정 적용
        issues = sortIssues(issues, currentIssueSort, currentIssueSortDir);

        const typeLabels = { bug: '버그', feature: '기능', improvement: '개선' };
        const statusColors = {
            open: 'bg-red-100 text-red-600',
            in_progress: 'bg-yellow-100 text-yellow-600',
            resolved: 'bg-green-100 text-green-600',
            closed: 'bg-gray-100 text-gray-600'
        };
        const statusLabels = { open: '열림', in_progress: '진행중', resolved: '해결됨', closed: '종료' };

        // 테이블 헤더
        let html = `
        <table class="w-full text-sm">
            <thead class="bg-gray-50 text-xs text-gray-500 uppercase">
                <tr>
                    <th class="w-8 px-2 py-2"></th>
                    <th class="w-10 px-1 py-2 text-center font-medium">긴급</th>
                    <th class="w-16 px-2 py-2 text-center font-medium">타입</th>
                    <th class="px-2 py-2 text-left font-medium">이슈명</th>
                    <th class="w-32 px-2 py-2 text-left font-medium">연결 작업</th>
                    <th class="w-24 px-2 py-2 text-center font-medium">시작일</th>
                    <th class="w-24 px-2 py-2 text-center font-medium">마감일</th>
                    <th class="w-16 px-2 py-2 text-center font-medium">상태</th>
                    <th class="w-40 px-2 py-2 text-center font-medium">변경</th>
                    <th class="w-12 px-2 py-2"></th>
                </tr>
            </thead>
            <tbody class="divide-y divide-gray-100">`;

        issues.forEach(issue => {
            html += `
            <tr class="hover:bg-gray-50">
                <td class="px-2 py-1.5 text-center">
                    <input type="checkbox" class="issue-checkbox w-4 h-4 rounded border-gray-300" data-id="${issue.id}">
                </td>
                <td class="px-1 py-1.5 text-center">
                    <button onclick="toggleIssueUrgent(${issue.id})" class="w-6 h-6 flex items-center justify-center rounded hover:bg-gray-100 transition ${issue.is_urgent ? 'text-red-500' : 'text-gray-300 hover:text-gray-400'}" title="${issue.is_urgent ? '긴급 해제' : '긴급 설정'}">
                        <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M12.395 2.553a1 1 0 00-1.45-.385c-.345.23-.614.558-.822.88-.214.33-.403.713-.57 1.116-.334.804-.614 1.768-.84 2.734a31.365 31.365 0 00-.613 3.58 2.64 2.64 0 01-.945-1.067c-.328-.68-.398-1.534-.398-2.654A1 1 0 005.05 6.05 6.981 6.981 0 003 11a7 7 0 1011.95-4.95c-.592-.591-.98-.985-1.348-1.467-.363-.476-.724-1.063-1.207-2.03zM12.12 15.12A3 3 0 017 13s.879.5 2.5.5c0-1 .5-4 1.25-4.5.5 1 .786 1.293 1.371 1.879A2.99 2.99 0 0113 13a2.99 2.99 0 01-.879 2.121z" clip-rule="evenodd"/></svg>
                    </button>
                </td>
                <td class="px-2 py-1.5 text-center">
                    <span class="text-xs text-gray-600">${typeLabels[issue.type] || issue.type}</span>
                </td>
                <td class="px-2 py-1.5">
                    <span class="font-medium text-gray-800 ${issue.is_urgent ? 'text-red-600' : ''}">${issue.title}</span>
                </td>
                <td class="px-2 py-1.5 text-xs text-gray-500 truncate max-w-[120px]" title="${issue.task?.title || ''}">
                    ${issue.task ? issue.task.title : '-'}
                </td>
                <td class="px-2 py-1.5 text-center text-xs text-gray-500">
                    ${issue.start_date ? formatDate(issue.start_date) : '-'}
                </td>
                <td class="px-2 py-1.5 text-center text-xs ${issue.due_date && new Date(issue.due_date) < new Date() && issue.status !== 'resolved' && issue.status !== 'closed' ? 'text-red-500 font-medium' : 'text-gray-500'}">
                    ${issue.due_date ? formatDate(issue.due_date) : '-'}
                </td>
                <td class="px-2 py-1.5 text-center">
                    <span class="px-1.5 py-0.5 text-xs rounded ${statusColors[issue.status]}">${statusLabels[issue.status]}</span>
                </td>
                <td class="px-2 py-1.5 text-center">
                    <div class="flex justify-center gap-0.5">
                        <button onclick="changeIssueStatus(${issue.id}, 'in_progress')" class="px-1.5 py-0.5 text-xs rounded border ${issue.status === 'in_progress' ? 'bg-yellow-500 text-white border-yellow-500' : 'border-gray-300 text-gray-600 hover:bg-gray-100'}" title="진행중으로 변경">진행</button>
                        <button onclick="changeIssueStatus(${issue.id}, 'resolved')" class="px-1.5 py-0.5 text-xs rounded border ${issue.status === 'resolved' ? 'bg-green-500 text-white border-green-500' : 'border-gray-300 text-gray-600 hover:bg-gray-100'}" title="해결됨으로 변경">해결</button>
                        <button onclick="changeIssueStatus(${issue.id}, 'closed')" class="px-1.5 py-0.5 text-xs rounded border ${issue.status === 'closed' ? 'bg-gray-500 text-white border-gray-500' : 'border-gray-300 text-gray-600 hover:bg-gray-100'}" title="종료로 변경">종료</button>
                    </div>
                </td>
                <td class="px-2 py-1.5 text-center">
                    <button onclick="editIssue(${issue.id})" class="text-gray-400 hover:text-blue-600" title="이슈 수정">
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
                    </button>
                </td>
            </tr>`;
        });

        html += '</tbody></table>';
        container.innerHTML = html;
    }

    // 작업 긴급 토글
    async function toggleTaskUrgent(taskId) {
        await fetch(`/api/admin/pm/tasks/${taskId}/toggle-urgent`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }
        });
        loadTasks();
    }

    // 이슈 긴급 토글
    async function toggleIssueUrgent(issueId) {
        await fetch(`/api/admin/pm/issues/${issueId}/toggle-urgent`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }
        });
        loadIssues();
    }

    // 서브 이슈 긴급 토글 (작업 탭 아코디언 내)
    async function toggleSubIssueUrgent(issueId, taskId) {
        await fetch(`/api/admin/pm/issues/${issueId}/toggle-urgent`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }
        });
        loadTasks(); // 작업 탭 아코디언 업데이트
        loadIssues(); // 이슈 탭도 동기화
    }

    // 작업 상태 변경
    async function changeTaskStatus(taskId, status) {
        await fetch(`/api/admin/pm/tasks/${taskId}/status`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify({ status })
        });
        loadTasks();
    }

    // 이슈 상태 변경 (이슈 탭)
    async function changeIssueStatus(issueId, status) {
        await fetch(`/api/admin/pm/issues/${issueId}/status`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify({ status })
        });

        // 이슈가 "진행"으로 변경될 때, 연결된 작업이 "할일"이면 자동으로 "진행중"으로 변경
        if (status === 'in_progress') {
            const issue = issuesData.find(i => i.id === issueId);
            if (issue && issue.task_id) {
                const task = tasksData.find(t => t.id === issue.task_id);
                if (task && task.status === 'todo') {
                    await fetch(`/api/admin/pm/tasks/${issue.task_id}/status`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
                        body: JSON.stringify({ status: 'in_progress' })
                    });
                }
            }
        }

        loadIssues();
        loadTasks(); // 작업 탭 진행률도 업데이트
    }

    // 서브 이슈 상태 변경 (작업 탭 아코디언 내)
    async function changeSubIssueStatus(issueId, status, taskId = null) {
        await fetch(`/api/admin/pm/issues/${issueId}/status`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify({ status })
        });

        // 이슈가 "진행"으로 변경될 때, 연결된 작업이 "할일"이면 자동으로 "진행중"으로 변경
        if (status === 'in_progress' && taskId) {
            const task = tasksData.find(t => t.id === taskId);
            if (task && task.status === 'todo') {
                await fetch(`/api/admin/pm/tasks/${taskId}/status`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
                    body: JSON.stringify({ status: 'in_progress' })
                });
            }
        }

        loadTasks(); // 진행률 즉시 반영
        loadIssues(); // 이슈 탭도 동기화
    }

    // 작업 모달
    function openTaskModal() {
        document.getElementById('taskModalTitle').textContent = '작업 추가';
        document.getElementById('taskForm').reset();
        document.getElementById('taskId').value = '';
        document.getElementById('taskModal').classList.remove('hidden');
    }

    function closeTaskModal() {
        document.getElementById('taskModal').classList.add('hidden');
    }

    async function editTask(taskId) {
        const response = await fetch(`/api/admin/pm/tasks/${taskId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': csrfToken }
        });
        const result = await response.json();
        if (result.success) {
            const task = result.data;
            document.getElementById('taskModalTitle').textContent = '작업 수정';
            document.getElementById('taskId').value = task.id;
            document.getElementById('taskTitle').value = task.title;
            document.getElementById('taskDescription').value = task.description || '';
            document.getElementById('taskStatus').value = task.status;
            document.getElementById('taskPriority').value = task.priority;
            document.getElementById('taskDueDate').value = task.due_date || '';
            document.getElementById('taskModal').classList.remove('hidden');
        }
    }

    document.getElementById('taskForm').addEventListener('submit', async function(e) {
        e.preventDefault();
        const formData = new FormData(this);
        const taskId = formData.get('task_id');
        const data = Object.fromEntries(formData.entries());
        delete data.task_id;

        const url = taskId ? `/api/admin/pm/tasks/${taskId}` : '/api/admin/pm/tasks';
        const method = taskId ? 'PUT' : 'POST';

        const response = await fetch(url, {
            method,
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify(data)
        });
        const result = await response.json();

        if (result.success) {
            closeTaskModal();
            loadTasks();
        } else {
            showToast(result.message || '저장에 실패했습니다.', 'error');
        }
    });

    // 이슈 모달
    function openIssueModal() {
        document.getElementById('issueModalTitle').textContent = '이슈 추가';
        document.getElementById('issueForm').reset();
        document.getElementById('issueId').value = '';
        document.getElementById('issueModal').classList.remove('hidden');
    }

    function closeIssueModal() {
        document.getElementById('issueModal').classList.add('hidden');
    }

    // 작업에 연결된 이슈 추가 (작업 탭에서 호출)
    function openIssueModalForTask(taskId) {
        document.getElementById('issueModalTitle').textContent = '이슈 추가';
        document.getElementById('issueForm').reset();
        document.getElementById('issueId').value = '';
        document.getElementById('issueTaskId').value = taskId; // 작업 ID 미리 설정
        document.getElementById('issueModal').classList.remove('hidden');
    }

    async function editIssue(issueId) {
        const response = await fetch(`/api/admin/pm/issues/${issueId}`, {
            headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': csrfToken }
        });
        const result = await response.json();
        if (result.success) {
            const issue = result.data;
            document.getElementById('issueModalTitle').textContent = '이슈 수정';
            document.getElementById('issueId').value = issue.id;
            document.getElementById('issueTitle').value = issue.title;
            document.getElementById('issueDescription').value = issue.description || '';
            document.getElementById('issueType').value = issue.type;
            document.getElementById('issueStatus').value = issue.status;
            document.getElementById('issueTaskId').value = issue.task_id || '';
            document.getElementById('issueStartDate').value = issue.start_date ? formatDate(issue.start_date) : '';
            document.getElementById('issueDueDate').value = issue.due_date ? formatDate(issue.due_date) : '';
            document.getElementById('issueEstimatedHours').value = issue.estimated_hours || '';
            // 팀/담당자/고객사
            document.getElementById('issueTeam').value = issue.team || '';
            document.getElementById('issueAssigneeName').value = issue.assignee_name || '';
            document.getElementById('issueClient').value = issue.client || '';
            document.getElementById('issueModal').classList.remove('hidden');
        }
    }

    document.getElementById('issueForm').addEventListener('submit', async function(e) {
        e.preventDefault();
        const formData = new FormData(this);
        const issueId = formData.get('issue_id');
        const data = Object.fromEntries(formData.entries());
        delete data.issue_id;

        const url = issueId ? `/api/admin/pm/issues/${issueId}` : '/api/admin/pm/issues';
        const method = issueId ? 'PUT' : 'POST';

        const response = await fetch(url, {
            method,
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify(data)
        });
        const result = await response.json();

        if (result.success) {
            closeIssueModal();
            loadIssues();
            loadTasks(); // 작업 탭 아코디언도 업데이트
        } else {
            showToast(result.message || '저장에 실패했습니다.', 'error');
        }
    });

    // 일괄 작업
    function getSelectedTaskIds() {
        return Array.from(document.querySelectorAll('.task-checkbox:checked')).map(cb => parseInt(cb.dataset.id));
    }

    function getSelectedIssueIds() {
        return Array.from(document.querySelectorAll('.issue-checkbox:checked')).map(cb => parseInt(cb.dataset.id));
    }

    async function handleTaskBulkAction() {
        const select = document.getElementById('taskBulkAction');
        const [action, value] = select.value.split(':');
        const ids = getSelectedTaskIds();

        if (!action || ids.length === 0) {
            select.value = '';
            if (action) showToast('선택된 작업이 없습니다.', 'warning');
            return;
        }

        if (action === 'delete') {
            showConfirm(`${ids.length}개 작업을 삭제하시겠습니까?`, async () => {
                await executeBulkTaskAction(select, ids, action, value);
            }, { title: '일괄 삭제', icon: 'warning' });
            return;
        }

        await executeBulkTaskAction(select, ids, action, value);
    }

    async function executeBulkTaskAction(select, ids, action, value) {
        await fetch('/api/admin/pm/tasks/bulk', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify({ ids, action, value })
        });

        select.value = '';
        loadTasks();
    }

    async function handleIssueBulkAction() {
        const select = document.getElementById('issueBulkAction');
        const [action, value] = select.value.split(':');
        const ids = getSelectedIssueIds();

        if (!action || ids.length === 0) {
            select.value = '';
            if (action) showToast('선택된 이슈가 없습니다.', 'warning');
            return;
        }

        if (action === 'delete') {
            showConfirm(`${ids.length}개 이슈를 삭제하시겠습니까?`, async () => {
                await executeBulkIssueAction(select, ids, action, value);
            }, { title: '일괄 삭제', icon: 'warning' });
            return;
        }

        await executeBulkIssueAction(select, ids, action, value);
    }

    async function executeBulkIssueAction(select, ids, action, value) {
        await fetch('/api/admin/pm/issues/bulk', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
            body: JSON.stringify({ ids, action, value })
        });

        select.value = '';
        loadIssues();
    }

    // 작업 삭제
    async function deleteTask(taskId) {
        const task = tasksData.find(t => t.id === taskId);
        const taskName = task ? task.title : '이 작업';

        showDeleteConfirm(`"${taskName}"`, async () => {
            const response = await fetch(`/api/admin/pm/tasks/${taskId}`, {
                method: 'DELETE',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }
            });
            const result = await response.json();

            if (result.success) {
                loadTasks();
                loadIssues(); // 연결된 이슈도 업데이트
            } else {
                showToast(result.message || '삭제에 실패했습니다.', 'error');
            }
        });
    }

    // 이슈 삭제
    async function deleteIssue(issueId, taskId = null) {
        const issue = issuesData.find(i => i.id === issueId);
        const issueName = issue ? issue.title : '이 이슈';

        showDeleteConfirm(`"${issueName}"`, async () => {
            const response = await fetch(`/api/admin/pm/issues/${issueId}`, {
                method: 'DELETE',
                headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }
            });
            const result = await response.json();

            if (result.success) {
                loadTasks(); // 작업 탭 아코디언 업데이트
                loadIssues(); // 이슈 탭 업데이트
            } else {
                showToast(result.message || '삭제에 실패했습니다.', 'error');
            }
        });
    }
</script>
@endpush
