
import React, { useState, useEffect, useMemo } from 'react';
import { createRoot } from 'react-dom/client';
import { 
  Calendar as CalendarIcon, Users, LayoutDashboard, Loader2, 
  ChevronLeft, ChevronRight, CheckCircle2, Circle, 
  Plus, Trash2, Edit2, UserPlus, Phone, Briefcase, X, Save, Search, Lock, Key, MapPin, ChevronDown, ChevronUp, AlertCircle, Check, CalendarDays
} from 'lucide-react';

// --- Configuration ---
const ACCESS_PASSWORD = 'duk@2026';

// --- Interfaces ---
interface Employee {
  id: number;
  name: string;
  role: string;
  phone?: string;
  is_deleted?: number;
}

interface Site {
  id: number;
  name: string;
  description?: string;
  is_deleted?: number;
  start_date?: string;
  end_date?: string;
}

interface Attendance {
  id: number;
  employeeId: number;
  siteId: number;
  workDate: string;
  employeeName?: string;
  employeeRole?: string;
  employeeDeleted?: number;
  siteName?: string;
  siteDeleted?: number;
}

const API_BASE = '/api';

// --- Helpers ---
// 한국 시간 기준으로 YYYY-MM-DD 문자열을 반환하는 함수
const getKSTDateString = () => {
  return new Intl.DateTimeFormat('en-CA', {
    timeZone: 'Asia/Seoul',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  }).format(new Date());
};

// --- Login Gate ---
const LoginGate = ({ onAuthenticate }: { onAuthenticate: () => void }) => {
  const [password, setPassword] = useState('');
  const [error, setError] = useState(false);
  const handleLogin = (e: React.FormEvent) => {
    e.preventDefault();
    if (password === ACCESS_PASSWORD) {
      sessionStorage.setItem('site_auth', 'true');
      onAuthenticate();
    } else {
      setError(true);
      setTimeout(() => setError(false), 500);
      setPassword('');
    }
  };
  return (
    <div className="min-h-screen bg-slate-900 flex items-center justify-center p-6 font-['Pretendard']">
      <div className={`max-w-md w-full bg-white/10 backdrop-blur-xl p-10 rounded-[2.5rem] border border-white/20 shadow-2xl transition-all duration-300 ${error ? 'animate-shake border-red-500/50' : ''}`}>
        <div className="flex flex-col items-center text-center space-y-6">
          <div className="w-20 h-20 bg-emerald-600 rounded-3xl flex items-center justify-center text-white shadow-2xl shadow-emerald-500/20 transform -rotate-6"><Lock size={40} /></div>
          <div><h1 className="text-2xl font-black text-white tracking-tight">현장관리 Pro</h1><p className="text-slate-400 font-bold mt-2">비밀번호를 입력하세요.</p></div>
          <form onSubmit={handleLogin} className="w-full space-y-4">
            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="비밀번호" className="w-full bg-white/5 border-2 border-white/10 rounded-2xl py-4 px-6 text-white font-bold outline-none focus:border-emerald-500 focus:bg-white/10" autoFocus />
            <button type="submit" className="w-full bg-emerald-600 text-white py-4 rounded-2xl font-black text-lg shadow-xl hover:bg-emerald-500 transition-all">접속하기</button>
          </form>
          {error && <p className="text-red-400 font-bold text-sm animate-pulse">틀렸습니다.</p>}
        </div>
      </div>
      <style>{`@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-8px); } 75% { transform: translateX(8px); } } .animate-shake { animation: shake 0.2s ease-in-out 0s 2; }`}</style>
    </div>
  );
};

// --- Site Manager ---
const SiteManager = ({ sites, onAdd, onUpdate, onDelete }) => {
  const [isAdding, setIsAdding] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [form, setForm] = useState({ name: '', description: '', start_date: '', end_date: '' });
  
  const handleSubmit = async () => {
    if (!form.name) return alert("현장명을 입력하세요.");
    if (editingId) { await onUpdate(editingId, form); setEditingId(null); }
    else { await onAdd(form); setIsAdding(false); }
    setForm({ name: '', description: '', start_date: '', end_date: '' });
  };
  
  return (
    <div className="space-y-6 p-4 animate-in fade-in duration-500">
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 bg-white p-6 rounded-3xl shadow-sm border border-slate-100">
        <div><h2 className="text-2xl font-black text-slate-800">현장 관리</h2><p className="text-slate-500 text-sm font-semibold">활성 현장: <span className="text-emerald-600 font-black">{sites.length}곳</span></p></div>
        {!isAdding && !editingId && (<button onClick={() => setIsAdding(true)} className="flex items-center gap-2 bg-emerald-600 text-white px-6 py-3 rounded-2xl font-black shadow-lg"><MapPin size={18} /> 현장 추가</button>)}
      </div>
      {(isAdding || editingId) && (
        <div className="bg-white p-8 rounded-3xl border-2 border-emerald-500 shadow-xl space-y-6 animate-in zoom-in-95">
          <h3 className="text-xl font-black text-emerald-800 flex items-center gap-2">{editingId ? <Edit2 size={24}/> : <Plus size={24}/>} {editingId ? '현장 정보 수정' : '새 현장'}</h3>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
            <div className="space-y-2 w-full min-w-0">
               <label className="text-xs font-black text-slate-400 uppercase">현장명</label>
               <input value={form.name} onChange={e => setForm({...form, name: e.target.value})} placeholder="현장 이름" className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none box-border" />
            </div>
            <div className="space-y-2 w-full min-w-0">
               <label className="text-xs font-black text-slate-400 uppercase">비고</label>
               <input value={form.description} onChange={e => setForm({...form, description: e.target.value})} placeholder="간략한 설명" className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none box-border" />
            </div>
            <div className="space-y-2 w-full min-w-0">
               <label className="text-xs font-black text-slate-400 uppercase">시작일</label>
               <input type="date" value={form.start_date} onChange={e => setForm({...form, start_date: e.target.value})} className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none box-border appearance-none min-w-0" />
            </div>
            <div className="space-y-2 w-full min-w-0">
               <label className="text-xs font-black text-slate-400 uppercase">종료일</label>
               <input type="date" value={form.end_date} onChange={e => setForm({...form, end_date: e.target.value})} className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none box-border appearance-none min-w-0" />
            </div>
          </div>
          <div className="flex flex-col sm:flex-row gap-3 pt-2">
            <button onClick={handleSubmit} className="flex-[2] bg-emerald-600 text-white py-4 rounded-xl font-black shadow-lg hover:bg-emerald-700 transition-colors">저장하기</button>
            <button onClick={() => {setIsAdding(false); setEditingId(null); setForm({name:'',description:'', start_date:'', end_date:''});}} className="flex-1 bg-slate-100 text-slate-500 py-4 rounded-xl font-black hover:bg-slate-200 transition-colors">취소</button>
          </div>
        </div>
      )}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {sites.map(site => (
          <div key={site.id} className="bg-white p-6 rounded-3xl shadow-sm border border-slate-100 flex flex-col group hover:border-emerald-200 transition-all">
            <div className="flex justify-between items-start mb-4">
              <div className="flex items-center gap-4">
                <div className="w-14 h-14 bg-emerald-50 text-emerald-600 rounded-2xl flex items-center justify-center font-black text-xl"><MapPin size={24}/></div>
                <div><p className="font-black text-lg text-slate-800 leading-tight">{site.name}</p><p className="text-[10px] font-bold text-slate-400 mt-1 uppercase">{site.description || '정보 없음'}</p></div>
              </div>
              <div className="flex gap-1 opacity-100 md:opacity-0 group-hover:opacity-100 transition-opacity">
                <button onClick={() => {setEditingId(site.id); setForm({name:site.name, description:site.description||'', start_date: site.start_date||'', end_date: site.end_date||''}); setIsAdding(false);}} className="p-2 text-slate-400 hover:text-emerald-600 hover:bg-emerald-50 rounded-lg"><Edit2 size={18}/></button>
                <button onClick={() => onDelete(site.id)} className="p-2 text-slate-400 hover:text-red-500 hover:bg-red-50 rounded-lg"><Trash2 size={18}/></button>
              </div>
            </div>
            <div className="mt-auto pt-4 border-t border-slate-50 flex items-center gap-2 text-slate-400 text-[10px] font-bold">
               <CalendarDays size={14}/> {site.start_date && site.end_date ? `${site.start_date} ~ ${site.end_date}` : '기간 미지정'}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// --- Employee Manager ---
const EmployeeManager = ({ employees, onAdd, onUpdate, onDelete }) => {
  const [isAdding, setIsAdding] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [form, setForm] = useState({ name: '', role: '', phone: '' });
  const handleSubmit = async () => {
    if (!form.name || !form.role) return alert("필수 정보를 입력하세요.");
    if (editingId) { await onUpdate(editingId, form); setEditingId(null); }
    else { await onAdd(form); setIsAdding(false); }
    setForm({ name: '', role: '', phone: '' });
  };
  return (
    <div className="space-y-6 p-4 animate-in fade-in duration-500">
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 bg-white p-6 rounded-3xl shadow-sm border border-slate-100">
        <div><h2 className="text-2xl font-black text-slate-800">인력 명부</h2><p className="text-slate-500 text-sm font-semibold">현재 관리 인원: <span className="text-emerald-600 font-black">{employees.length}명</span></p></div>
        {!isAdding && !editingId && (<button onClick={() => setIsAdding(true)} className="flex items-center gap-2 bg-emerald-600 text-white px-6 py-3 rounded-2xl font-black shadow-lg shadow-emerald-100"><UserPlus size={18} /> 신규 등록</button>)}
      </div>
      {(isAdding || editingId) && (
        <div className="bg-white p-8 rounded-3xl border-2 border-emerald-500 shadow-xl space-y-6 animate-in zoom-in-95">
          <h3 className="text-xl font-black text-emerald-800 flex items-center gap-2">{editingId ? <Edit2 size={24}/> : <Plus size={24}/>} {editingId ? '인원 수정' : '신규 등록'}</h3>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            <input value={form.name} onChange={e => setForm({...form, name: e.target.value})} placeholder="이름" className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none" />
            <input value={form.role} onChange={e => setForm({...form, role: e.target.value})} placeholder="공종/직책" className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none" />
            <input value={form.phone} onChange={e => setForm({...form, phone: e.target.value})} placeholder="연락처" className="w-full bg-slate-50 p-4 rounded-xl font-bold border-2 border-transparent focus:border-emerald-200 outline-none" />
          </div>
          <div className="flex flex-col sm:flex-row gap-3 pt-2">
            <button onClick={handleSubmit} className="flex-[2] bg-emerald-600 text-white py-4 rounded-xl font-black shadow-lg hover:bg-emerald-700">저장</button>
            <button onClick={() => {setIsAdding(false); setEditingId(null); setForm({name:'',role:'',phone:''});}} className="flex-1 bg-slate-100 text-slate-500 py-4 rounded-xl font-black hover:bg-slate-200">취소</button>
          </div>
        </div>
      )}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {employees.map(emp => (
          <div key={emp.id} className="bg-white p-6 rounded-3xl shadow-sm border border-slate-100 flex flex-col group hover:border-emerald-200 transition-all">
            <div className="flex justify-between items-start mb-4">
              <div className="flex items-center gap-4">
                <div className="w-14 h-14 bg-emerald-50 text-emerald-600 rounded-2xl flex items-center justify-center font-black text-xl leading-none">{emp.name[0]}</div>
                <div><p className="font-black text-lg text-slate-800 leading-tight">{emp.name}</p><p className="text-xs font-bold text-slate-400 uppercase tracking-tighter">{emp.role}</p></div>
              </div>
              <div className="flex gap-1 opacity-100 md:opacity-0 group-hover:opacity-100 transition-opacity">
                <button onClick={() => {setEditingId(emp.id); setForm({name:emp.name, role:emp.role, phone:emp.phone||''}); setIsAdding(false);}} className="p-2 text-slate-400 hover:text-emerald-600 hover:bg-emerald-50 rounded-lg"><Edit2 size={18}/></button>
                <button onClick={() => onDelete(emp.id)} className="p-2 text-slate-400 hover:text-red-500 hover:bg-red-50 rounded-lg"><Trash2 size={18}/></button>
              </div>
            </div>
            <div className="mt-auto pt-4 border-t border-slate-50 flex items-center gap-2 text-slate-500 text-sm font-bold"><Phone size={14}/> {emp.phone || '연락처 없음'}</div>
          </div>
        ))}
      </div>
    </div>
  );
};

// --- Calendar ---
const Calendar = ({ employees, sites, attendances, onToggle, onClearSiteRecord }) => {
  const [currentDate, setCurrentDate] = useState(new Date());
  // 초기 선택 날짜도 KST 기준으로 설정
  const todayKST = useMemo(() => getKSTDateString(), []);
  const [selectedDate, setSelectedDate] = useState<string | null>(todayKST);
  const [editingSites, setEditingSites] = useState<Record<number, boolean>>({});

  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const firstDay = new Date(year, month, 1).getDay();

  const daySummaries = useMemo(() => {
    const map: Record<string, { siteId: number; siteName: string; count: number }[]> = {};
    attendances.forEach(a => {
      if (!map[a.workDate]) map[a.workDate] = [];
      let entry = map[a.workDate].find(e => e.siteId === a.siteId);
      if (!entry) {
        entry = { siteId: a.siteId, siteName: a.siteName || '알수없음', count: 0 };
        map[a.workDate].push(entry);
      }
      entry.count++;
    });
    return map;
  }, [attendances]);

  const sitesForSelectedDate = useMemo(() => {
    if (!selectedDate) return [];
    const activeSitesInPeriod = sites.filter(site => {
       if (!site.start_date || !site.end_date) return true;
       return selectedDate >= site.start_date && selectedDate <= site.end_date;
    });
    const relevantAttendances = attendances.filter(a => a.workDate === selectedDate);
    const resultSites = [...activeSitesInPeriod.map(s => ({ ...s, isInactiveRecord: false }))];
    relevantAttendances.forEach(a => {
       if (!resultSites.find(s => s.id === a.siteId)) {
          resultSites.push({ 
            id: a.siteId, 
            name: a.siteName || '기록된 현장', 
            is_deleted: a.siteDeleted || 0,
            isInactiveRecord: true 
          });
       }
    });
    return resultSites;
  }, [selectedDate, sites, attendances]);

  const toggleEditMode = (siteId: number) => {
    setEditingSites(prev => ({ ...prev, [siteId]: !prev[siteId] }));
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 p-4 animate-in fade-in duration-500">
      <div className="lg:col-span-2 space-y-4">
        <div className="bg-white p-6 rounded-3xl shadow-sm border border-slate-100 flex items-center justify-between">
          <button onClick={() => setCurrentDate(new Date(year, month - 1, 1))} className="p-3 hover:bg-slate-50 rounded-full transition-all"><ChevronLeft size={24}/></button>
          <div className="text-center"><h2 className="text-2xl font-black text-slate-800">{year}년 {month + 1}월</h2></div>
          <button onClick={() => setCurrentDate(new Date(year, month + 1, 1))} className="p-3 hover:bg-slate-50 rounded-full transition-all"><ChevronRight size={24}/></button>
        </div>
        <div className="bg-white p-4 md:p-8 rounded-3xl shadow-sm border border-slate-100">
          <div className="grid grid-cols-7 mb-4">
            {['일','월','화','수','목','금','토'].map((d, i) => (
              <div key={d} className={`text-center py-2 text-[10px] font-black uppercase ${i===0?'text-rose-400':i===6?'text-blue-400':'text-slate-300'}`}>{d}</div>
            ))}
          </div>
          <div className="grid grid-cols-7 gap-2 md:gap-3">
            {Array.from({ length: firstDay }).map((_, i) => <div key={i} className="aspect-square bg-slate-50/20 rounded-2xl" />)}
            {Array.from({ length: daysInMonth }).map((_, i) => {
              const d = i + 1;
              const key = `${year}-${String(month+1).padStart(2,'0')}-${String(d).padStart(2,'0')}`;
              const summaries = daySummaries[key] || [];
              const isSelected = selectedDate === key;
              // 실시간 한국 시간 기준으로 오늘 판단
              const isToday = todayKST === key;
              
              return (
                <button key={d} onClick={() => setSelectedDate(key)} className={`relative aspect-square rounded-2xl border-2 flex flex-col items-center justify-start py-2 gap-0.5 transition-all ${isSelected ? 'border-emerald-500 bg-emerald-50 ring-4 ring-emerald-500/10 scale-105 z-10 shadow-sm' : 'border-transparent hover:border-slate-200 hover:bg-slate-50'}`}>
                  <span className={`text-base font-black leading-none mb-1 ${isSelected ? 'text-emerald-700' : isToday ? 'text-emerald-500 underline underline-offset-4 ring-2 ring-emerald-500/20' : 'text-slate-700'}`}>{d}</span>
                  <div className="w-full px-1 flex flex-col items-center gap-0.5 overflow-hidden">
                    {summaries.slice(0, 3).map((s, idx) => (
                      <div key={idx} className="w-full text-[7px] md:text-[8px] bg-white border border-emerald-100 rounded px-1 py-0.5 truncate text-emerald-800 font-bold text-center leading-none">{s.siteName}:{s.count}</div>
                    ))}
                    {summaries.length > 3 && <div className="text-[6px] text-emerald-400 font-black">+{summaries.length-3}</div>}
                  </div>
                  {isToday && !isSelected && <div className="absolute top-1 right-1 w-1.5 h-1.5 bg-emerald-500 rounded-full" />}
                </button>
              );
            })}
          </div>
        </div>
      </div>
      
      <div className="bg-white p-6 rounded-3xl shadow-sm border border-slate-100 flex flex-col h-full min-h-[550px] sticky top-8 overflow-hidden">
        {selectedDate ? (
          <div className="flex-1 flex flex-col space-y-6 overflow-hidden">
            <div className="pb-4 border-b border-slate-100 shrink-0">
              <h3 className="text-xl font-black text-slate-800 tracking-tight">{selectedDate} 상세 내역</h3>
              <p className="text-sm font-bold text-slate-400">배정 인원을 관리하세요.</p>
            </div>
            <div className="flex-1 overflow-y-auto pr-2 space-y-5 custom-scrollbar pb-10">
              {sitesForSelectedDate.length === 0 ? (
                <div className="text-center py-20">
                  <p className="text-slate-300 font-bold mb-2">선택한 날짜에 활성 현장이 없습니다.</p>
                  <p className="text-[10px] text-slate-400">현장 관리에서 공사 기간을 확인하세요.</p>
                </div>
              ) : (
                sitesForSelectedDate.map(site => {
                  const siteAttendances = attendances.filter(a => a.workDate === selectedDate && a.siteId === site.id);
                  const isEditing = editingSites[site.id];
                  return (
                    <div key={site.id} className={`border-2 rounded-2xl overflow-hidden transition-all ${site.is_deleted ? 'border-rose-100 bg-rose-50/10' : 'border-slate-50'}`}>
                      <div className="flex items-center justify-between p-4 bg-white/50 border-b border-slate-50">
                        <div className="flex items-center gap-3">
                          <MapPin size={18} className={siteAttendances.length > 0 ? 'text-emerald-500' : 'text-slate-300'}/>
                          <div className="text-left">
                            <p className={`font-black leading-tight text-sm ${site.is_deleted ? 'text-rose-500' : 'text-slate-800'}`}>{site.name} {site.is_deleted ? '(삭제됨)' : ''}</p>
                            <p className="text-[9px] font-bold text-slate-400">투입: {siteAttendances.length}명</p>
                          </div>
                        </div>
                        <div className="flex items-center gap-2">
                           <button onClick={() => toggleEditMode(site.id)} className={`px-4 py-1.5 rounded-full font-black text-[10px] transition-all ${isEditing ? 'bg-emerald-600 text-white shadow-md' : 'bg-slate-100 text-slate-500'}`}>
                             {isEditing ? '완료' : '인원수정'}
                           </button>
                           {siteAttendances.length > 0 && (
                             <button onClick={() => onClearSiteRecord(site.id, selectedDate)} className="p-2 text-rose-300 hover:text-rose-600" title="기록 전체삭제"><Trash2 size={14}/></button>
                           )}
                        </div>
                      </div>

                      <div className="p-4 bg-white/30 space-y-3">
                        {isEditing ? (
                          <div className="space-y-2 animate-in slide-in-from-top-2">
                            <p className="text-[9px] font-black text-emerald-600 mb-2 uppercase tracking-widest">배정 가능 인력</p>
                            {employees.map(emp => {
                              const active = siteAttendances.some(a => a.employeeId === emp.id);
                              return (
                                <button key={emp.id} onClick={() => onToggle(emp.id, site.id, selectedDate)} className={`w-full flex items-center justify-between p-3 rounded-xl border-2 transition-all ${active ? 'border-emerald-200 bg-emerald-50/50 text-emerald-800' : 'border-slate-50 hover:border-slate-100 text-slate-500'}`}>
                                  <div className="text-left"><p className="font-bold text-xs">{emp.name}</p><p className="text-[9px] font-bold opacity-60 tracking-tighter">{emp.role}</p></div>
                                  {active ? <CheckCircle2 size={16} className="text-emerald-500" /> : <Circle size={16} className="text-slate-200" />}
                                </button>
                              );
                            })}
                          </div>
                        ) : (
                          <div className="flex flex-wrap gap-2 animate-in fade-in">
                            {siteAttendances.length > 0 ? (
                              siteAttendances.map(a => (
                                <div key={a.id} className={`flex items-center gap-1.5 px-3 py-1.5 rounded-xl border ${a.employeeDeleted === 1 ? 'bg-rose-50 border-rose-100 text-rose-700' : 'bg-emerald-50 border-emerald-100 text-emerald-800 shadow-sm'}`}>
                                  <span className="text-[9px] font-black opacity-60">[{a.employeeRole}]</span>
                                  <span className="text-xs font-black">{a.employeeName}</span>
                                  {a.employeeDeleted === 1 && <AlertCircle size={10} className="opacity-50 ml-1 text-rose-400"/>}
                                </div>
                              ))
                            ) : (
                              <p className="text-[10px] text-slate-300 font-bold py-2">배정 인원 없음</p>
                            )}
                          </div>
                        )}
                      </div>
                    </div>
                  );
                })
              )}
            </div>
          </div>
        ) : (
          <div className="h-full flex flex-col items-center justify-center opacity-30 text-center space-y-4 py-20"><CalendarIcon size={64}/><p className="font-black text-xl leading-tight">날짜를 선택하세요.</p></div>
        )}
      </div>
    </div>
  );
};

// --- App ---
const App = () => {
  const [view, setView] = useState('CALENDAR');
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [employees, setEmployees] = useState<Employee[]>([]);
  const [sites, setSites] = useState<Site[]>([]);
  const [attendances, setAttendances] = useState<Attendance[]>([]);
  const [loading, setLoading] = useState(true);

  const fetchData = async () => {
    try {
      const [eRes, sRes, aRes] = await Promise.all([
        fetch(`${API_BASE}/employees`), fetch(`${API_BASE}/sites`), fetch(`${API_BASE}/attendances`)
      ]);
      setEmployees(await eRes.json());
      setSites(await sRes.json());
      setAttendances(await aRes.json());
    } catch(e) { console.error(e); } finally { setLoading(false); }
  };

  useEffect(() => { 
    if (sessionStorage.getItem('site_auth') === 'true') setIsAuthenticated(true);
    fetchData(); 
  }, []);

  const handleAddEmployee = async (form) => {
    const res = await fetch(`${API_BASE}/employees`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(form) });
    const { id } = await res.json(); setEmployees(prev => [...prev, { ...form, id }]);
  };
  const handleUpdateEmployee = async (id, form) => {
    await fetch(`${API_BASE}/employees/${id}`, { method: 'PUT', headers: {'Content-Type':'application/json'}, body: JSON.stringify(form) });
    setEmployees(prev => prev.map(e => e.id === id ? { ...e, ...form } : e));
  };
  const handleDeleteEmployee = async (id) => {
    if (!confirm("인력을 명부에서 제외하시겠습니까? 과거 투입 기록은 보존됩니다.")) return;
    await fetch(`${API_BASE}/employees/${id}`, { method: 'DELETE' });
    setEmployees(prev => prev.filter(e => e.id !== id));
  };
  const handleAddSite = async (form) => {
    const res = await fetch(`${API_BASE}/sites`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(form) });
    const { id } = await res.json(); setSites(prev => [...prev, { ...form, id }]);
  };
  const handleUpdateSite = async (id, form) => {
    await fetch(`${API_BASE}/sites/${id}`, { method: 'PUT', headers: {'Content-Type':'application/json'}, body: JSON.stringify(form) });
    setSites(prev => prev.map(s => s.id === id ? { ...s, ...form } : s));
  };
  const handleDeleteSite = async (id) => {
    if (!confirm("현장을 관리 목록에서 제외하시겠습니까? 과거 투입 기록은 보존됩니다.")) return;
    await fetch(`${API_BASE}/sites/${id}`, { method: 'DELETE' });
    setSites(prev => prev.filter(s => s.id !== id));
  };
  const handleToggle = async (employeeId, siteId, workDate) => {
    await fetch(`${API_BASE}/attendances/toggle`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ employeeId, siteId, workDate }) });
    fetchData();
  };
  const handleClearSiteRecord = async (siteId, workDate) => {
    if (!confirm("이 현장의 해당 날짜 기록을 모두 삭제하시겠습니까?")) return;
    const siteAtts = attendances.filter(a => a.siteId === siteId && a.workDate === workDate);
    for (const att of siteAtts) {
      await fetch(`${API_BASE}/attendances/toggle`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ employeeId: att.employeeId, siteId, workDate }) });
    }
    fetchData();
  };

  if (!isAuthenticated) return <LoginGate onAuthenticate={() => setIsAuthenticated(true)} />;
  if (loading) return <div className="h-screen flex flex-col items-center justify-center text-emerald-600 font-black gap-4 bg-slate-50"><Loader2 className="animate-spin w-12 h-12"/><p className="text-slate-800 font-bold">동기화 중...</p></div>;

  return (
    <div className="min-h-screen bg-slate-50 flex flex-col lg:flex-row font-['Pretendard']">
      <nav className="fixed left-0 top-0 bottom-0 w-72 bg-white border-r border-slate-100 hidden lg:flex flex-col p-8 z-50">
        <div className="flex items-center gap-4 mb-12 px-2"><div className="w-12 h-12 bg-emerald-600 rounded-2xl flex items-center justify-center text-white shadow-lg shadow-emerald-100"><LayoutDashboard size={28}/></div><div><h1 className="text-xl font-black text-slate-800 leading-tight">현장관리 Pro</h1><p className="text-[10px] font-black text-emerald-600 uppercase tracking-widest mt-1">Archive Edition</p></div></div>
        <div className="space-y-3 flex-1">
          <button onClick={() => setView('CALENDAR')} className={`w-full flex items-center gap-4 px-6 py-4 rounded-2xl font-black transition-all ${view === 'CALENDAR' ? 'bg-emerald-600 text-white shadow-lg shadow-emerald-100 translate-x-1' : 'text-slate-400 hover:bg-slate-50'}`}><CalendarIcon size={20}/> <span>근무 현황판</span></button>
          <button onClick={() => setView('SITES')} className={`w-full flex items-center gap-4 px-6 py-4 rounded-2xl font-black transition-all ${view === 'SITES' ? 'bg-emerald-600 text-white shadow-lg shadow-emerald-100 translate-x-1' : 'text-slate-400 hover:bg-slate-50'}`}><MapPin size={20}/> <span>현장 관리</span></button>
          <button onClick={() => setView('EMPLOYEES')} className={`w-full flex items-center gap-4 px-6 py-4 rounded-2xl font-black transition-all ${view === 'EMPLOYEES' ? 'bg-emerald-600 text-white shadow-lg shadow-emerald-100 translate-x-1' : 'text-slate-400 hover:bg-slate-50'}`}><Users size={20}/> <span>인력 명부</span></button>
        </div>
        <button onClick={() => { sessionStorage.removeItem('site_auth'); setIsAuthenticated(false); }} className="mt-auto w-full flex items-center gap-3 px-6 py-3 text-slate-400 hover:text-red-500 rounded-xl font-bold transition-all"><Lock size={16}/> 로그아웃</button>
      </nav>
      <nav className="fixed bottom-0 left-0 right-0 h-20 bg-white border-t flex lg:hidden items-center justify-around z-50 rounded-t-[2.5rem] shadow-2xl px-6">
        <button onClick={() => setView('CALENDAR')} className={`p-2 transition-all ${view === 'CALENDAR' ? 'text-emerald-600 scale-110' : 'text-slate-300'}`}><CalendarIcon size={24}/></button>
        <button onClick={() => setView('SITES')} className={`p-2 transition-all ${view === 'SITES' ? 'text-emerald-600 scale-110' : 'text-slate-300'}`}><MapPin size={24}/></button>
        <button onClick={() => setView('EMPLOYEES')} className={`p-2 transition-all ${view === 'EMPLOYEES' ? 'text-emerald-600 scale-110' : 'text-slate-300'}`}><Users size={24}/></button>
      </nav>
      <main className="flex-1 lg:pl-72 min-h-screen">
        <div className="max-w-7xl mx-auto py-6 lg:py-12 pb-24 lg:pb-12 px-4">
          {view === 'CALENDAR' && <Calendar employees={employees} sites={sites} attendances={attendances} onToggle={handleToggle} onClearSiteRecord={handleClearSiteRecord} />}
          {view === 'SITES' && <SiteManager sites={sites} onAdd={handleAddSite} onUpdate={handleUpdateSite} onDelete={handleDeleteSite} />}
          {view === 'EMPLOYEES' && <EmployeeManager employees={employees} onAdd={handleAddEmployee} onUpdate={handleUpdateEmployee} onDelete={handleDeleteEmployee} />}
        </div>
      </main>
    </div>
  );
};

const root = createRoot(document.getElementById('root')!);
root.render(<App />);

