/**
 * 모바일 친화적 캘린더 컴포넌트
 * 터치 및 스와이프 지원, 날짜 범위 선택 기능
 */

class MobileCalendar {
    constructor(containerId, options = {}) {
        this.container = document.getElementById(containerId);
        this.options = {
            locale: 'ko-KR',
            startDate: null,
            endDate: null,
            maxRange: 90, // 최대 90일 범위
            onDateSelect: null,
            onRangeSelect: null,
            ...options
        };
        
        this.currentDate = new Date();
        this.selectedStartDate = null;
        this.selectedEndDate = null;
        this.isSelecting = false;
        this.touchStartX = 0;
        this.touchStartY = 0;
        
        this.init();
    }

    init() {
        this.render();
        this.bindEvents();
    }

    render() {
        const calendarHTML = `
            <div class="mobile-calendar">
                <!-- 빠른 선택 버튼들 -->
                <div class="quick-select-buttons mb-4">
                    <div class="flex gap-2 overflow-x-auto pb-2">
                        <button class="quick-btn" data-range="today">오늘</button>
                        <button class="quick-btn" data-range="week">이번 주</button>
                        <button class="quick-btn" data-range="month">이번 달</button>
                        <button class="quick-btn" data-range="last7">최근 7일</button>
                        <button class="quick-btn" data-range="last30">최근 30일</button>
                        <button class="quick-btn" data-range="all">전체</button>
                    </div>
                </div>

                <!-- 캘린더 헤더 -->
                <div class="calendar-header flex items-center justify-between mb-4">
                    <button class="nav-btn" id="prevMonth">
                        <i class="fas fa-chevron-left"></i>
                    </button>
                    <h3 class="month-year text-lg font-semibold" id="monthYear"></h3>
                    <button class="nav-btn" id="nextMonth">
                        <i class="fas fa-chevron-right"></i>
                    </button>
                </div>

                <!-- 요일 헤더 -->
                <div class="weekdays grid grid-cols-7 gap-1 mb-2">
                    <div class="weekday">일</div>
                    <div class="weekday">월</div>
                    <div class="weekday">화</div>
                    <div class="weekday">수</div>
                    <div class="weekday">목</div>
                    <div class="weekday">금</div>
                    <div class="weekday">토</div>
                </div>

                <!-- 날짜 그리드 -->
                <div class="calendar-grid grid grid-cols-7 gap-1" id="calendarGrid">
                    <!-- 날짜들이 여기에 동적으로 생성됩니다 -->
                </div>

                <!-- 선택된 범위 표시 -->
                <div class="selected-range mt-4 p-3 bg-blue-50 rounded-lg" id="selectedRange" style="display: none;">
                    <div class="flex items-center justify-between">
                        <span class="text-sm text-blue-700" id="rangeText"></span>
                        <button class="clear-btn text-blue-600 hover:text-blue-800" id="clearRange">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                </div>

                <!-- 사용법 안내 -->
                <div class="usage-hint mt-3 text-xs text-gray-500 text-center">
                    📅 날짜를 터치하여 시작일을 선택하고, 다시 터치하여 종료일을 선택하세요
                </div>
            </div>
        `;

        this.container.innerHTML = calendarHTML;
        this.updateCalendar();
    }

    updateCalendar() {
        const year = this.currentDate.getFullYear();
        const month = this.currentDate.getMonth();
        
        // 월/년 표시 업데이트
        document.getElementById('monthYear').textContent = 
            `${year}년 ${month + 1}월`;

        // 캘린더 그리드 생성
        this.generateCalendarGrid(year, month);
    }

    generateCalendarGrid(year, month) {
        const grid = document.getElementById('calendarGrid');
        const firstDay = new Date(year, month, 1);
        const lastDay = new Date(year, month + 1, 0);
        const startDate = new Date(firstDay);
        startDate.setDate(startDate.getDate() - firstDay.getDay());

        let html = '';
        const today = new Date();
        
        // 6주 표시 (42일)
        for (let i = 0; i < 42; i++) {
            const date = new Date(startDate);
            date.setDate(startDate.getDate() + i);
            
            const isCurrentMonth = date.getMonth() === month;
            const isToday = this.isSameDate(date, today);
            const isSelected = this.isDateInRange(date);
            const isStart = this.selectedStartDate && this.isSameDate(date, this.selectedStartDate);
            const isEnd = this.selectedEndDate && this.isSameDate(date, this.selectedEndDate);
            
            let classes = ['calendar-day'];
            if (!isCurrentMonth) classes.push('other-month');
            if (isToday) classes.push('today');
            if (isSelected) classes.push('selected');
            if (isStart) classes.push('range-start');
            if (isEnd) classes.push('range-end');
            
            html += `
                <div class="${classes.join(' ')}" 
                     data-date="${date.toISOString().split('T')[0]}"
                     data-timestamp="${date.getTime()}">
                    ${date.getDate()}
                </div>
            `;
        }
        
        grid.innerHTML = html;
    }

    bindEvents() {
        // 빠른 선택 버튼들
        this.container.querySelectorAll('.quick-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                const range = e.target.dataset.range;
                this.selectQuickRange(range);
            });
        });

        // 월 네비게이션
        document.getElementById('prevMonth').addEventListener('click', () => {
            this.currentDate.setMonth(this.currentDate.getMonth() - 1);
            this.updateCalendar();
        });

        document.getElementById('nextMonth').addEventListener('click', () => {
            this.currentDate.setMonth(this.currentDate.getMonth() + 1);
            this.updateCalendar();
        });

        // 날짜 선택
        this.container.addEventListener('click', (e) => {
            if (e.target.classList.contains('calendar-day')) {
                this.handleDateClick(e.target);
            }
        });

        // 터치 이벤트 (스와이프 지원)
        this.container.addEventListener('touchstart', (e) => {
            this.touchStartX = e.touches[0].clientX;
            this.touchStartY = e.touches[0].clientY;
        });

        this.container.addEventListener('touchend', (e) => {
            if (!this.touchStartX || !this.touchStartY) return;

            const touchEndX = e.changedTouches[0].clientX;
            const touchEndY = e.changedTouches[0].clientY;
            
            const diffX = this.touchStartX - touchEndX;
            const diffY = this.touchStartY - touchEndY;

            // 수평 스와이프가 수직 스와이프보다 클 때만 처리
            if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) {
                if (diffX > 0) {
                    // 왼쪽으로 스와이프 - 다음 달
                    this.currentDate.setMonth(this.currentDate.getMonth() + 1);
                } else {
                    // 오른쪽으로 스와이프 - 이전 달
                    this.currentDate.setMonth(this.currentDate.getMonth() - 1);
                }
                this.updateCalendar();
            }

            this.touchStartX = 0;
            this.touchStartY = 0;
        });

        // 범위 지우기
        document.getElementById('clearRange').addEventListener('click', () => {
            this.clearSelection();
        });
    }

    handleDateClick(dayElement) {
        const dateStr = dayElement.dataset.date;
        const date = new Date(dateStr + 'T00:00:00');

        if (!this.selectedStartDate || (this.selectedStartDate && this.selectedEndDate)) {
            // 새로운 선택 시작
            this.selectedStartDate = date;
            this.selectedEndDate = null;
            this.isSelecting = true;
        } else if (this.selectedStartDate && !this.selectedEndDate) {
            // 종료일 선택
            if (date < this.selectedStartDate) {
                // 시작일보다 이전 날짜를 선택하면 시작일로 설정
                this.selectedEndDate = this.selectedStartDate;
                this.selectedStartDate = date;
            } else {
                this.selectedEndDate = date;
            }
            this.isSelecting = false;
            
            // 범위가 너무 크면 제한
            const daysDiff = Math.abs(this.selectedEndDate - this.selectedStartDate) / (1000 * 60 * 60 * 24);
            if (daysDiff > this.options.maxRange) {
                alert(`최대 ${this.options.maxRange}일까지만 선택할 수 있습니다.`);
                this.clearSelection();
                return;
            }
        }

        this.updateCalendar();
        this.updateSelectedRange();
        
        // 콜백 호출
        if (this.selectedStartDate && this.selectedEndDate && this.options.onRangeSelect) {
            this.options.onRangeSelect(this.selectedStartDate, this.selectedEndDate);
        }
    }

    selectQuickRange(range) {
        const today = new Date();
        let startDate, endDate;

        switch (range) {
            case 'today':
                startDate = endDate = new Date(today);
                break;
            case 'week':
                startDate = new Date(today);
                startDate.setDate(today.getDate() - today.getDay());
                endDate = new Date(startDate);
                endDate.setDate(startDate.getDate() + 6);
                break;
            case 'month':
                startDate = new Date(today.getFullYear(), today.getMonth(), 1);
                endDate = new Date(today.getFullYear(), today.getMonth() + 1, 0);
                break;
            case 'last7':
                endDate = new Date(today);
                startDate = new Date(today);
                startDate.setDate(today.getDate() - 6);
                break;
            case 'last30':
                endDate = new Date(today);
                startDate = new Date(today);
                startDate.setDate(today.getDate() - 29);
                break;
            case 'all':
                this.clearSelection();
                if (this.options.onRangeSelect) {
                    this.options.onRangeSelect(null, null);
                }
                return;
        }

        this.selectedStartDate = startDate;
        this.selectedEndDate = endDate;
        this.updateCalendar();
        this.updateSelectedRange();

        if (this.options.onRangeSelect) {
            this.options.onRangeSelect(startDate, endDate);
        }
    }

    updateSelectedRange() {
        const rangeElement = document.getElementById('selectedRange');
        const rangeText = document.getElementById('rangeText');

        if (this.selectedStartDate && this.selectedEndDate) {
            const startStr = this.formatDate(this.selectedStartDate);
            const endStr = this.formatDate(this.selectedEndDate);
            const daysDiff = Math.ceil((this.selectedEndDate - this.selectedStartDate) / (1000 * 60 * 60 * 24)) + 1;
            
            rangeText.textContent = `${startStr} ~ ${endStr} (${daysDiff}일)`;
            rangeElement.style.display = 'block';
        } else if (this.selectedStartDate) {
            rangeText.textContent = `시작일: ${this.formatDate(this.selectedStartDate)} (종료일을 선택하세요)`;
            rangeElement.style.display = 'block';
        } else {
            rangeElement.style.display = 'none';
        }
    }

    clearSelection() {
        this.selectedStartDate = null;
        this.selectedEndDate = null;
        this.isSelecting = false;
        this.updateCalendar();
        this.updateSelectedRange();
    }

    isDateInRange(date) {
        if (!this.selectedStartDate) return false;
        if (!this.selectedEndDate) return this.isSameDate(date, this.selectedStartDate);
        
        return date >= this.selectedStartDate && date <= this.selectedEndDate;
    }

    isSameDate(date1, date2) {
        return date1.toDateString() === date2.toDateString();
    }

    formatDate(date) {
        return date.toLocaleDateString('ko-KR', {
            month: 'short',
            day: 'numeric'
        });
    }

    // 외부에서 호출할 수 있는 메서드들
    getSelectedRange() {
        return {
            startDate: this.selectedStartDate,
            endDate: this.selectedEndDate
        };
    }

    setSelectedRange(startDate, endDate) {
        this.selectedStartDate = startDate;
        this.selectedEndDate = endDate;
        this.updateCalendar();
        this.updateSelectedRange();
    }
}

// 전역으로 노출
window.MobileCalendar = MobileCalendar;
