/**
 * Persian Date Picker for Rating System
 * Automatically switches between Persian and Gregorian calendars based on locale
 */

class PersianDatePicker {
    constructor() {
        this.locale = this.detectLocale();
        this.isPersian = this.locale === 'fa';
        this.init();
    }

    detectLocale() {
        // Check URL for locale
        const urlPath = window.location.pathname;
        if (urlPath.startsWith('/fa/') || urlPath.startsWith('/fa-')) {
            return 'fa';
        }

        // Check HTML lang attribute
        const htmlLang = document.documentElement.lang;
        if (htmlLang && htmlLang.startsWith('fa')) {
            return 'fa';
        }

        // Check meta tag
        const metaLocale = document.querySelector('meta[name="locale"]');
        if (metaLocale && metaLocale.content === 'fa') {
            return 'fa';
        }

        return 'en';
    }

    init() {
        if (this.isPersian) {
            this.loadPersianDatePicker();
        } else {
            this.initGregorianDatePicker();
        }
    }

    loadPersianDatePicker() {
        // Use simple Persian date input without external library
        this.initSimplePersianDatePicker();
    }

    initSimplePersianDatePicker() {
        const dateInputs = document.querySelectorAll('input[type="date"], input[name="visit_date"], input[name="stay_date"]');

        dateInputs.forEach(input => {
            // Create wrapper
            const wrapper = document.createElement('div');
            wrapper.style.position = 'relative';
            wrapper.style.display = 'inline-block';
            wrapper.style.width = '100%';

            // Insert wrapper
            input.parentNode.insertBefore(wrapper, input);
            wrapper.appendChild(input);

            // Create Persian date input
            const persianInput = document.createElement('input');
            persianInput.type = 'text';
            persianInput.className = input.className;

            // Set appropriate placeholder based on input name
            let placeholder = 'تاریخ (مثال: ۱۴۰۳/۰۱/۱۵)';
            if (input.name === 'visit_date') {
                placeholder = 'تاریخ بازدید (مثال: ۱۴۰۳/۰۱/۱۵)';
            } else if (input.name === 'stay_date') {
                placeholder = 'تاریخ اقامت (مثال: ۱۴۰۳/۰۱/۱۵)';
            }

            persianInput.placeholder = placeholder;
            persianInput.style.direction = 'rtl';
            persianInput.style.textAlign = 'right';
            persianInput.style.fontFamily = 'inherit';

            // Hide original input and show Persian input
            input.style.display = 'none';
            wrapper.appendChild(persianInput);

            // Create calendar button
            const calendarBtn = document.createElement('button');
            calendarBtn.type = 'button';
            calendarBtn.innerHTML = '📅';
            calendarBtn.style.cssText = `
                position: absolute;
                left: 10px;
                top: 50%;
                transform: translateY(-50%);
                border: none;
                background: none;
                font-size: 1.2rem;
                cursor: pointer;
                padding: 0.25rem;
                border-radius: 4px;
                z-index: 10;
            `;
            wrapper.appendChild(calendarBtn);

            // Add input validation and conversion
            persianInput.addEventListener('input', (e) => {
                let value = e.target.value;

                // Convert Persian numbers to English
                value = this.convertToEnglishNumbers(value);

                // Auto-format as user types
                value = value.replace(/[^\d]/g, ''); // Remove non-digits
                if (value.length >= 4) {
                    value = value.substring(0, 4) + '/' + value.substring(4);
                }
                if (value.length >= 7) {
                    value = value.substring(0, 7) + '/' + value.substring(7, 9);
                }

                // Convert back to Persian numbers for display
                const persianValue = this.convertToFarsiNumbers(value);
                e.target.value = persianValue;

                // Validate and convert to Gregorian
                if (value.length === 10) { // YYYY/MM/DD format
                    const gregorianDate = this.persianToGregorianSimple(value);
                    if (gregorianDate) {
                        input.value = gregorianDate;

                        // Trigger change event
                        const event = new Event('change', { bubbles: true });
                        input.dispatchEvent(event);
                    }
                }
            });

            // Calendar button click
            calendarBtn.addEventListener('click', () => {
                this.showPersianCalendar(persianInput, input);
            });

            // Add helper text
            const helper = document.createElement('small');
            helper.style.display = 'block';
            helper.style.marginTop = '0.25rem';
            helper.style.color = '#6c757d';
            helper.style.fontSize = '0.8rem';

            let helperText = 'فرمت: سال/ماه/روز (مثال: ۱۴۰۳/۰۱/۱۵) یا روی 📅 کلیک کنید';
            if (input.name === 'stay_date') {
                helperText = 'تاریخ اقامت خود را وارد کنید - فرمت: سال/ماه/روز (مثال: ۱۴۰۳/۰۱/۱۵) یا روی 📅 کلیک کنید';
            }

            helper.textContent = helperText;
            wrapper.appendChild(helper);
        });
    }

    showPersianCalendar(persianInput, hiddenInput) {
        // Remove existing calendar
        const existingCalendar = document.querySelector('.persian-calendar-popup');
        if (existingCalendar) {
            existingCalendar.remove();
        }

        // Create calendar popup
        const calendar = document.createElement('div');
        calendar.className = 'persian-calendar-popup';
        calendar.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            border: 2px solid #ddd;
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            z-index: 9999;
            padding: 1rem;
            direction: rtl;
            font-family: inherit;
            min-width: 300px;
        `;

        // Get current Persian date
        const today = new Date();
        const persianToday = this.gregorianToJalali(today.getFullYear(), today.getMonth() + 1, today.getDate());
        let currentYear = persianToday[0];
        let currentMonth = persianToday[1];

        const persianMonths = [
            'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور',
            'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
        ];

        const renderCalendar = () => {
            calendar.innerHTML = `
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
                    <button type="button" class="cal-nav-btn" data-action="prev-year">«</button>
                    <button type="button" class="cal-nav-btn" data-action="prev-month">‹</button>
                    <div style="font-weight: bold; font-size: 1.1rem;">
                        ${this.convertToFarsiNumbers(String(currentYear))} ${persianMonths[currentMonth - 1]}
                    </div>
                    <button type="button" class="cal-nav-btn" data-action="next-month">›</button>
                    <button type="button" class="cal-nav-btn" data-action="next-year">»</button>
                </div>
                <div class="calendar-grid" style="display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center;">
                    <div style="font-weight: bold; padding: 0.5rem;">ش</div>
                    <div style="font-weight: bold; padding: 0.5rem;">ی</div>
                    <div style="font-weight: bold; padding: 0.5rem;">د</div>
                    <div style="font-weight: bold; padding: 0.5rem;">س</div>
                    <div style="font-weight: bold; padding: 0.5rem;">چ</div>
                    <div style="font-weight: bold; padding: 0.5rem;">پ</div>
                    <div style="font-weight: bold; padding: 0.5rem;">ج</div>
                </div>
                <div style="display: flex; justify-content: space-between; margin-top: 1rem;">
                    <button type="button" class="cal-action-btn" data-action="today">امروز</button>
                    <button type="button" class="cal-action-btn" data-action="close">بستن</button>
                </div>
            `;

            // Add days
            const grid = calendar.querySelector('.calendar-grid');
            const daysInMonth = currentMonth <= 6 ? 31 : (currentMonth < 12 ? 30 : (this.isJalaliLeapYear(currentYear) ? 30 : 29));

            // Calculate first day of month (simplified)
            const firstDayGregorian = this.jalaliToGregorian(currentYear, currentMonth, 1);
            const firstDayOfWeek = new Date(firstDayGregorian[0], firstDayGregorian[1] - 1, firstDayGregorian[2]).getDay();
            const adjustedFirstDay = (firstDayOfWeek + 1) % 7; // Adjust for Persian week starting on Saturday

            // Add empty cells for days before month starts
            for (let i = 0; i < adjustedFirstDay; i++) {
                const emptyCell = document.createElement('div');
                emptyCell.style.padding = '0.5rem';
                grid.appendChild(emptyCell);
            }

            // Add days of month
            for (let day = 1; day <= daysInMonth; day++) {
                const dayCell = document.createElement('div');
                dayCell.textContent = this.convertToFarsiNumbers(String(day));
                dayCell.style.cssText = `
                    padding: 0.5rem;
                    cursor: pointer;
                    border-radius: 4px;
                    transition: background-color 0.2s;
                `;

                // Highlight today
                if (currentYear === persianToday[0] && currentMonth === persianToday[1] && day === persianToday[2]) {
                    dayCell.style.backgroundColor = '#007bff';
                    dayCell.style.color = 'white';
                }

                dayCell.addEventListener('mouseenter', () => {
                    if (dayCell.style.backgroundColor !== 'rgb(0, 123, 255)') {
                        dayCell.style.backgroundColor = '#f0f0f0';
                    }
                });

                dayCell.addEventListener('mouseleave', () => {
                    if (dayCell.style.backgroundColor !== 'rgb(0, 123, 255)') {
                        dayCell.style.backgroundColor = '';
                    }
                });

                dayCell.addEventListener('click', () => {
                    const selectedDate = `${currentYear}/${String(currentMonth).padStart(2, '0')}/${String(day).padStart(2, '0')}`;
                    const persianDate = this.convertToFarsiNumbers(selectedDate);
                    persianInput.value = persianDate;

                    // Convert to Gregorian
                    const gregorianDate = this.persianToGregorianSimple(selectedDate);
                    if (gregorianDate) {
                        hiddenInput.value = gregorianDate;
                        const event = new Event('change', { bubbles: true });
                        hiddenInput.dispatchEvent(event);
                    }

                    calendar.remove();
                });

                grid.appendChild(dayCell);
            }
        };

        // Navigation event listeners
        calendar.addEventListener('click', (e) => {
            const action = e.target.dataset.action;
            switch (action) {
                case 'prev-year':
                    currentYear--;
                    renderCalendar();
                    break;
                case 'next-year':
                    currentYear++;
                    renderCalendar();
                    break;
                case 'prev-month':
                    currentMonth--;
                    if (currentMonth < 1) {
                        currentMonth = 12;
                        currentYear--;
                    }
                    renderCalendar();
                    break;
                case 'next-month':
                    currentMonth++;
                    if (currentMonth > 12) {
                        currentMonth = 1;
                        currentYear++;
                    }
                    renderCalendar();
                    break;
                case 'today':
                    currentYear = persianToday[0];
                    currentMonth = persianToday[1];
                    renderCalendar();
                    break;
                case 'close':
                    calendar.remove();
                    break;
            }
        });

        // Style navigation buttons
        const style = document.createElement('style');
        style.textContent = `
            .cal-nav-btn, .cal-action-btn {
                background: #f8f9fa;
                border: 1px solid #ddd;
                padding: 0.5rem 0.75rem;
                border-radius: 4px;
                cursor: pointer;
                transition: background-color 0.2s;
            }
            .cal-nav-btn:hover, .cal-action-btn:hover {
                background: #e9ecef;
            }
        `;
        document.head.appendChild(style);

        renderCalendar();
        document.body.appendChild(calendar);

        // Close on outside click
        setTimeout(() => {
            document.addEventListener('click', function closeCalendar(e) {
                if (!calendar.contains(e.target)) {
                    calendar.remove();
                    document.removeEventListener('click', closeCalendar);
                }
            });
        }, 100);
    }

    initGregorianDatePicker() {
        const dateInputs = document.querySelectorAll('input[type="date"], input[name="visit_date"], input[name="stay_date"]');

        dateInputs.forEach(input => {
            // Set max date to today
            const today = new Date().toISOString().split('T')[0];
            input.max = today;

            // Add appropriate placeholder based on input name
            if (!input.placeholder) {
                if (input.name === 'visit_date') {
                    input.placeholder = 'Visit Date';
                } else if (input.name === 'stay_date') {
                    input.placeholder = 'Stay Date';
                } else {
                    input.placeholder = 'Date';
                }
            }
        });
    }

    persianToGregorianSimple(persianDate) {
        try {
            const parts = persianDate.split('/');
            if (parts.length !== 3) return null;

            const jy = parseInt(parts[0]);
            const jm = parseInt(parts[1]);
            const jd = parseInt(parts[2]);

            // Validate Persian date
            if (jy < 1300 || jy > 1500 || jm < 1 || jm > 12 || jd < 1 || jd > 31) {
                return null;
            }

            // Convert Persian to Gregorian using algorithm
            const gregorian = this.jalaliToGregorian(jy, jm, jd);

            // Format as YYYY-MM-DD
            const year = gregorian[0];
            const month = String(gregorian[1]).padStart(2, '0');
            const day = String(gregorian[2]).padStart(2, '0');

            return `${year}-${month}-${day}`;
        } catch (error) {
            console.error('Error converting Persian date:', error);
            return null;
        }
    }

    jalaliToGregorian(jy, jm, jd) {
        // Accurate Jalali to Gregorian conversion algorithm
        const PERSIAN_EPOCH = 1948321; // Julian day of 1/1/1 Persian calendar

        let epyear = jy - 979;
        let epbase = epyear - 33 * Math.floor(epyear / 33);
        let auxb = 0;

        if (epbase < 29) {
            auxb = Math.floor(epbase / 33) * 682 + Math.floor((epbase % 33) / 4) * 1461 + (epbase % 33 % 4) * 365;
        } else {
            auxb = Math.floor(epbase / 33) * 682 + Math.floor((epbase % 33) / 4) * 1461 + (epbase % 33 % 4) * 365 + 1;
        }

        let jday = PERSIAN_EPOCH + 33 * Math.floor(epyear / 33) * 682 + auxb;

        for (let i = 1; i < jm; i++) {
            if (i <= 6) {
                jday += 31;
            } else {
                jday += 30;
            }
        }

        jday += jd;

        // Convert Julian day to Gregorian
        let a = jday + 32044;
        let b = Math.floor((4 * a + 3) / 146097);
        let c = a - Math.floor((146097 * b) / 4);
        let d = Math.floor((4 * c + 3) / 1461);
        let e = c - Math.floor((1461 * d) / 4);
        let m = Math.floor((5 * e + 2) / 153);

        let day = e - Math.floor((153 * m + 2) / 5) + 1;
        let month = m + 3 - 12 * Math.floor(m / 10);
        let year = 100 * b + d - 4800 + Math.floor(m / 10);

        return [year, month, day];
    }



    get jalaliMonthDays() {
        return [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29];
    }

    isJalaliLeapYear(year) {
        // 33-year cycle leap year calculation for Persian calendar
        const cycle = year % 33;
        return [1, 5, 9, 13, 17, 22, 26, 30].includes(cycle);
    }

    gregorianToPersian(gregorianDate) {
        if (!gregorianDate) return '';

        const date = new Date(gregorianDate);
        if (window.persianDatepicker) {
            return window.persianDatepicker.unix(date.getTime()).format('YYYY/MM/DD');
        }
        return gregorianDate;
    }

    // Format dates for display
    formatDateForDisplay(dateString, includeTime = false) {
        if (!dateString) return '';

        const date = new Date(dateString);

        if (this.isPersian) {
            return this.formatPersianDate(date, includeTime);
        } else {
            return this.formatGregorianDate(date, includeTime);
        }
    }

    formatPersianDate(date, includeTime = false) {
        try {
            // Convert Gregorian to Persian
            const gregorian = this.gregorianToJalali(date.getFullYear(), date.getMonth() + 1, date.getDate());
            const persianMonths = [
                'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور',
                'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
            ];

            let formatted = `${this.convertToFarsiNumbers(gregorian[2])} ${persianMonths[gregorian[1] - 1]} ${this.convertToFarsiNumbers(gregorian[0])}`;

            if (includeTime) {
                const time = date.toLocaleTimeString('fa-IR', {
                    hour: '2-digit',
                    minute: '2-digit'
                });
                formatted += ' ساعت ' + this.convertToFarsiNumbers(time);
            }

            return formatted;
        } catch (error) {
            // Fallback to simple Persian numbers
            return this.convertToFarsiNumbers(date.toLocaleDateString('fa-IR'));
        }
    }

    gregorianToJalali(gy, gm, gd) {
        // Simple approximation for current dates (2020-2030)
        // This is a simplified version that works for current years

        // Base conversion: 2024-12-25 = 1403-10-05 (accurate reference point)
        const baseGregorian = { year: 2024, month: 12, day: 25 };
        const basePersian = { year: 1403, month: 10, day: 5 };

        // Calculate days difference from base date
        const gregorianDate = new Date(gy, gm - 1, gd);
        const baseDate = new Date(baseGregorian.year, baseGregorian.month - 1, baseGregorian.day);
        const daysDiff = Math.floor((gregorianDate - baseDate) / (24 * 60 * 60 * 1000));

        // Start from base Persian date
        let jy = basePersian.year;
        let jm = basePersian.month;
        let jd = basePersian.day + daysDiff;

        // Adjust for month overflow/underflow
        while (jd > this.getDaysInPersianMonth(jy, jm)) {
            jd -= this.getDaysInPersianMonth(jy, jm);
            jm++;
            if (jm > 12) {
                jm = 1;
                jy++;
            }
        }

        while (jd < 1) {
            jm--;
            if (jm < 1) {
                jm = 12;
                jy--;
            }
            jd += this.getDaysInPersianMonth(jy, jm);
        }

        return [jy, jm, jd];
    }

    getDaysInPersianMonth(year, month) {
        if (month <= 6) {
            return 31;
        } else if (month <= 11) {
            return 30;
        } else {
            return this.isJalaliLeapYear(year) ? 30 : 29;
        }
    }

    gregorianToJulian(year, month, day) {
        let a = Math.floor((14 - month) / 12);
        let y = year - a;
        let m = month + 12 * a - 3;

        return day + Math.floor((153 * m + 2) / 5) + 365 * y + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) + 1721119;
    }

    formatGregorianDate(date, includeTime = false) {
        let formatted = date.toLocaleDateString('en-US', {
            year: 'numeric',
            month: 'long',
            day: 'numeric'
        });

        if (includeTime) {
            const time = date.toLocaleTimeString('en-US', {
                hour: '2-digit',
                minute: '2-digit'
            });
            formatted += ' at ' + time;
        }

        return formatted;
    }

    convertToFarsiNumbers(str) {
        if (!str || typeof str !== 'string') {
            str = String(str || '');
        }
        const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
        return str.replace(/[0-9]/g, (digit) => farsiDigits[parseInt(digit)]);
    }

    convertToEnglishNumbers(str) {
        const englishDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];

        let result = str;
        farsiDigits.forEach((farsi, index) => {
            result = result.replace(new RegExp(farsi, 'g'), englishDigits[index]);
        });

        return result;
    }

    // Update existing dates in the page
    updateExistingDates() {
        // Update comment dates
        const commentDates = document.querySelectorAll('.comment-date');
        commentDates.forEach(element => {
            const originalDate = element.dataset.originalDate || element.textContent;
            if (originalDate && !element.dataset.updated) {
                element.textContent = this.formatDateForDisplay(originalDate, true);
                element.dataset.originalDate = originalDate;
                element.dataset.updated = 'true';
            }
        });

        // Update rating dates
        const ratingDates = document.querySelectorAll('.rating-date');
        ratingDates.forEach(element => {
            const originalDate = element.dataset.originalDate || element.textContent;
            if (originalDate && !element.dataset.updated) {
                element.textContent = this.formatDateForDisplay(originalDate, true);
                element.dataset.originalDate = originalDate;
                element.dataset.updated = 'true';
            }
        });
    }
}

// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    window.persianDatePickerInstance = new PersianDatePicker();

    // Update existing dates after a short delay to ensure content is loaded
    setTimeout(() => {
        window.persianDatePickerInstance.updateExistingDates();
    }, 500);
});

// Export for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
    module.exports = PersianDatePicker;
}
