export class DateRangePicker {
    constructor({ containerId, onChange, initialStartDate = '', initialEndDate = '' }) {
        this.container = document.getElementById(containerId);
        if (!this.container) return;

        this.trigger = this.container.querySelector('#date-picker-trigger');
        this.popover = this.container.querySelector('#date-picker-popover');
        this.backdrop = this.container.querySelector('#date-picker-backdrop');
        this.label = this.container.querySelector('#date-picker-label');
        
        this.startDisplay = this.container.querySelector('#picker-start-display');
        this.endDisplay = this.container.querySelector('#picker-end-display');
        
        this.prevBtn = this.container.querySelector('#prev-month-btn');
        this.nextBtn = this.container.querySelector('#next-month-btn');
        this.leftMonthLabel = this.container.querySelector('#left-month-label');
        this.rightMonthLabel = this.container.querySelector('#right-month-label');
        
        this.leftMonthName = this.container.querySelector('#left-month-name');
        this.rightMonthName = this.container.querySelector('#right-month-name');
        this.leftYearSelect = this.container.querySelector('#left-year-select');
        this.rightYearSelect = this.container.querySelector('#right-year-select');
        
        this.leftPane = this.container.querySelector('#left-calendar-pane');
        this.rightPane = this.container.querySelector('#right-calendar-pane');
        
        this.leftDaysContainer = this.container.querySelector('#left-days-container');
        this.rightDaysContainer = this.container.querySelector('#right-days-container');
        
        this.cancelBtn = this.container.querySelector('#picker-cancel-btn');
        this.applyBtn = this.container.querySelector('#picker-apply-btn');
        
        this.onChange = onChange;
        
        // Active dates (saved)
        this.startDate = initialStartDate ? new Date(initialStartDate) : null;
        this.endDate = initialEndDate ? new Date(initialEndDate) : null;
        
        // Temporary dates (being edited)
        this.tempStartDate = this.startDate ? new Date(this.startDate) : null;
        this.tempEndDate = this.endDate ? new Date(this.endDate) : null;
        
        // Calendar view month/year
        const today = new Date();
        if (this.endDate) {
            this.currentLeftMonth = this.endDate.getMonth();
            this.currentLeftYear = this.endDate.getFullYear();
        } else {
            this.currentLeftMonth = today.getMonth();
            this.currentLeftYear = today.getFullYear();
        }
        
        this.isOpen = false;
        this._init();
    }

    _init() {
        this._populateYearSelects();
        this._bindEvents();
        this._bindDisplayInputs();
        this._updateTriggerLabel();
        
        // Listen to language changes
        document.addEventListener('languageChanged', () => {
            if (this.isOpen) {
                this._renderCalendars();
            }
            this._updateTriggerLabel();
        });
    }

    _isEnglish() {
        if (typeof window.getLang === 'function') {
            const l = window.getLang();
            if (l === 'id' || l === 'en') return l === 'en';
        }
        try {
            const saved = localStorage.getItem('if_untan_lang');
            if (saved === 'id' || saved === 'en') return saved === 'en';
        } catch (e) {}
        const nav = (navigator.language || 'id').toLowerCase();
        return nav.startsWith('en');
    }

    _clearTime(date) {
        if (!date) return null;
        const d = new Date(date);
        d.setHours(0, 0, 0, 0);
        return d;
    }

    _datesEqual(d1, d2) {
        if (!d1 || !d2) return false;
        return d1.getFullYear() === d2.getFullYear() &&
               d1.getMonth() === d2.getMonth() &&
               d1.getDate() === d2.getDate();
    }

    _getRightMonthYear() {
        let m = this.currentLeftMonth + 1;
        let y = this.currentLeftYear;
        if (m > 11) {
            m = 0;
            y += 1;
        }
        return { month: m, year: y };
    }

    _navigateMonths(direction) {
        this.currentLeftMonth += direction;
        if (this.currentLeftMonth > 11) {
            this.currentLeftMonth = 0;
            this.currentLeftYear += 1;
        } else if (this.currentLeftMonth < 0) {
            this.currentLeftMonth = 11;
            this.currentLeftYear -= 1;
        }
        this._renderCalendars();
    }

    _renderCalendars() {
        const isEn = this._isEnglish();
        const monthNames = isEn ? 
          ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] :
          ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];

        const dayHeaders = isEn ?
          ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] :
          ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'];

        if (this.leftMonthName) {
            this.leftMonthName.textContent = monthNames[this.currentLeftMonth];
        }
        if (this.leftYearSelect) {
            this.leftYearSelect.value = this.currentLeftYear;
        }
        
        const rightMY = this._getRightMonthYear();
        if (this.rightMonthName) {
            this.rightMonthName.textContent = monthNames[rightMY.month];
        }
        if (this.rightYearSelect) {
            this.rightYearSelect.value = rightMY.year;
        }
        
        const drawHeaders = (pane) => {
            if (!pane) return;
            const dayHeadersEl = pane.querySelector('.day-headers');
            if (!dayHeadersEl) return;
            dayHeadersEl.innerHTML = '';
            dayHeaders.forEach(day => {
                const span = document.createElement('span');
                span.textContent = day;
                dayHeadersEl.appendChild(span);
            });
        };
        
        drawHeaders(this.leftPane);
        drawHeaders(this.rightPane);
        
        if (this.leftDaysContainer) {
            this._populateDaysContainer(this.leftDaysContainer, this.currentLeftMonth, this.currentLeftYear);
        }
        if (this.rightDaysContainer) {
            this._populateDaysContainer(this.rightDaysContainer, rightMY.month, rightMY.year);
        }
        
        this._updateDisplayInputs();
        this._updatePresetSelectionVisuals();
    }

    _populateDaysContainer(container, month, year) {
        container.innerHTML = '';
        
        const firstDay = new Date(year, month, 1);
        const numDays = new Date(year, month + 1, 0).getDate();
        
        let offset = (firstDay.getDay() + 6) % 7;
        
        for (let i = 0; i < offset; i++) {
            const cell = document.createElement('div');
            cell.className = 'day-cell empty';
            container.appendChild(cell);
        }
        
        const today = new Date();
        today.setHours(23, 59, 59, 999);
        
        for (let day = 1; day <= numDays; day++) {
            const cell = document.createElement('div');
            cell.className = 'day-cell';
            cell.textContent = day;
            
            const cellDate = new Date(year, month, day);
            cellDate.setHours(0, 0, 0, 0);
            
            if (cellDate > today) {
                cell.classList.add('disabled');
            } else {
                if (this.tempStartDate && this.tempEndDate) {
                    const start = this._clearTime(this.tempStartDate);
                    const end = this._clearTime(this.tempEndDate);
                    
                    if (this._datesEqual(cellDate, start)) {
                        cell.classList.add('range-start');
                    }
                    if (this._datesEqual(cellDate, end)) {
                        cell.classList.add('range-end');
                    }
                    if (cellDate > start && cellDate < end) {
                        cell.classList.add('range-between');
                    }
                } else if (this.tempStartDate && this._datesEqual(cellDate, this._clearTime(this.tempStartDate))) {
                    cell.classList.add('range-start');
                    cell.classList.add('range-end');
                }
                
                cell.addEventListener('click', () => {
                    this._handleDayClick(cellDate);
                });
            }
            
            container.appendChild(cell);
        }
    }

    _handleDayClick(date) {
        if (!this.tempStartDate || (this.tempStartDate && this.tempEndDate)) {
            this.tempStartDate = new Date(date);
            this.tempEndDate = null;
        } else {
            if (date < this.tempStartDate) {
                this.tempStartDate = new Date(date);
                this.tempEndDate = null;
            } else {
                this.tempEndDate = new Date(date);
            }
        }
        this._renderCalendars();
    }

    _formatDateDisplay(date) {
        if (!date) return '';
        const d = new Date(date);
        const dd = String(d.getDate()).padStart(2, '0');
        const mm = String(d.getMonth() + 1).padStart(2, '0');
        const yyyy = d.getFullYear();
        return `${dd}/${mm}/${yyyy}`;
    }

    _updateDisplayInputs() {
        if (this.startDisplay) {
            this.startDisplay.value = this._formatDateDisplay(this.tempStartDate);
        }
        if (this.endDisplay) {
            this.endDisplay.value = this._formatDateDisplay(this.tempEndDate);
        }
    }

    _calculatePreset(presetName) {
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        
        let start = null;
        let end = null;
        
        switch (presetName) {
            case 'today':
                start = new Date(today);
                end = new Date(today);
                break;
            case 'yesterday':
                start = new Date(today);
                start.setDate(today.getDate() - 1);
                end = new Date(start);
                break;
            case 'last7':
                end = new Date(today);
                start = new Date(today);
                start.setDate(today.getDate() - 6);
                break;
            case 'last14':
                end = new Date(today);
                start = new Date(today);
                start.setDate(today.getDate() - 13);
                break;
            case 'last30':
                end = new Date(today);
                start = new Date(today);
                start.setDate(today.getDate() - 29);
                break;
            case 'thisWeek':
                end = new Date(today);
                start = new Date(today);
                const day = today.getDay();
                const diff = today.getDate() - day + (day === 0 ? -6 : 1);
                start.setDate(diff);
                break;
            case 'lastWeek':
                const temp = new Date(today);
                const tempDay = temp.getDay();
                const tempDiff = temp.getDate() - tempDay + (tempDay === 0 ? -6 : 1);
                start = new Date(temp);
                start.setDate(tempDiff - 7);
                end = new Date(temp);
                end.setDate(tempDiff - 1);
                break;
            case 'thisMonth':
                start = new Date(today.getFullYear(), today.getMonth(), 1);
                end = new Date(today);
                break;
            case 'lastMonth':
                start = new Date(today.getFullYear(), today.getMonth() - 1, 1);
                end = new Date(today.getFullYear(), today.getMonth(), 0);
                break;
            case 'all':
            default:
                start = null;
                end = null;
                break;
        }
        return { start, end };
    }

    _handlePresetClick(presetName) {
        const { start, end } = this._calculatePreset(presetName);
        this.tempStartDate = start;
        this.tempEndDate = end;
        
        const today = new Date();
        if (this.tempEndDate) {
            this.currentLeftMonth = this.tempEndDate.getMonth();
            this.currentLeftYear = this.tempEndDate.getFullYear();
        } else {
            this.currentLeftMonth = today.getMonth();
            this.currentLeftYear = today.getFullYear();
        }
        this._renderCalendars();
    }

    _updatePresetSelectionVisuals() {
        this.container.querySelectorAll('.preset-btn').forEach(btn => {
            btn.classList.remove('active');
        });
        
        if (!this.tempStartDate && !this.tempEndDate) {
            this.container.querySelector('[data-preset="all"]')?.classList.add('active');
            return;
        }
        
        if (this.tempStartDate && this.tempEndDate) {
            const activePreset = ['today', 'yesterday', 'last7', 'last14', 'last30', 'thisWeek', 'lastWeek', 'thisMonth', 'lastMonth'].find(preset => {
                const { start, end } = this._calculatePreset(preset);
                return start && end &&
                       this._datesEqual(this.tempStartDate, start) &&
                       this._datesEqual(this.tempEndDate, end);
            });
            
            if (activePreset) {
                this.container.querySelector(`[data-preset="${activePreset}"]`)?.classList.add('active');
            }
        }
    }

    _updateTriggerLabel() {
        if (!this.startDate && !this.endDate) {
            if (this.label) {
                this.label.textContent = window.tpT?.('filter_all_time') || 'Semua Waktu';
                this.label.setAttribute('data-tp-i18n', 'filter_all_time');
            }
        } else {
            if (this.label) {
                this.label.removeAttribute('data-tp-i18n');
                const startFormatted = this._formatDateDisplay(this.startDate);
                const endFormatted = this._formatDateDisplay(this.endDate);
                if (this._datesEqual(this.startDate, this.endDate)) {
                    this.label.textContent = startFormatted;
                } else {
                    this.label.textContent = `${startFormatted} - ${endFormatted}`;
                }
            }
        }
    }

    _bindEvents() {
        this.trigger.addEventListener('click', (e) => {
            e.stopPropagation();
            this.toggle();
        });
        
        this.popover.addEventListener('click', (e) => {
            e.stopPropagation();
        });
        
        if (this.prevBtn) {
            this.prevBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                this._navigateMonths(-1);
            });
        }
        if (this.nextBtn) {
            this.nextBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                this._navigateMonths(1);
            });
        }
        
        const presetsList = this.container.querySelector('.presets-list');
        if (presetsList) {
            presetsList.addEventListener('click', (e) => {
                const btn = e.target.closest('.preset-btn');
                if (!btn) return;
                e.stopPropagation();
                const preset = btn.getAttribute('data-preset');
                this._handlePresetClick(preset);
            });
        }
        
        if (this.cancelBtn) {
            this.cancelBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                this._handleCancel();
            });
        }
        
        if (this.applyBtn) {
            this.applyBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                this._handleApply();
            });
        }
        
        if (this.backdrop) {
            this.backdrop.addEventListener('click', (e) => {
                e.stopPropagation();
                this._handleCancel();
            });
        }
        
        document.addEventListener('click', () => {
            if (this.isOpen) {
                this._handleCancel();
            }
        });
        
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && this.isOpen) {
                this._handleCancel();
            }
        });
    }

    _bindDisplayInputs() {
        const parseDate = (val) => {
            const m = val.trim().match(/^(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})$/);
            if (!m) return null;
            const d = parseInt(m[1], 10);
            const mon = parseInt(m[2], 10) - 1;
            const y = parseInt(m[3], 10);
            
            if (mon < 0 || mon > 11 || d < 1 || d > 31 || y < 1000 || y > 9999) return null;
            
            const testDate = new Date(y, mon, d);
            if (testDate.getFullYear() !== y || testDate.getMonth() !== mon || testDate.getDate() !== d) {
                return null;
            }
            return testDate;
        };

        const setupInput = (input, isStart) => {
            if (!input) return;
            
            input.addEventListener('keydown', (e) => {
                const CTRL_KEYS = new Set(['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter']);
                if (!/^\d$/.test(e.key) && e.key !== '/' && e.key !== '-' && e.key !== '.' && !CTRL_KEYS.has(e.key)) {
                    e.preventDefault();
                }
            });

            input.addEventListener('input', (e) => {
                if (e.inputType && e.inputType.startsWith('delete')) {
                    return;
                }
                
                let val = input.value.replace(/[^\d]/g, '');
                let formatted = val;
                if (val.length > 2) {
                    formatted = val.substring(0, 2) + '/' + val.substring(2);
                }
                if (val.length > 4) {
                    formatted = val.substring(0, 2) + '/' + val.substring(2, 4) + '/' + val.substring(4, 8);
                }
                input.value = formatted;

                const parsed = parseDate(formatted);
                if (parsed) {
                    const today = new Date();
                    today.setHours(23, 59, 59, 999);
                    if (parsed <= today) {
                        if (isStart) {
                            this.tempStartDate = parsed;
                            if (this.tempEndDate && this.tempEndDate < this.tempStartDate) {
                                this.tempEndDate = new Date(this.tempStartDate);
                            }
                        } else {
                            this.tempEndDate = parsed;
                            if (this.tempStartDate && this.tempStartDate > this.tempEndDate) {
                                this.tempStartDate = new Date(this.tempEndDate);
                            }
                        }
                        
                        this.currentLeftMonth = parsed.getMonth();
                        this.currentLeftYear = parsed.getFullYear();
                        
                        const rightMY = this._getRightMonthYear();
                        const isEn = this._isEnglish();
                        const monthNames = isEn ? 
                          ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] :
                          ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
                        if (this.leftMonthName) this.leftMonthName.textContent = monthNames[this.currentLeftMonth];
                        if (this.leftYearSelect) this.leftYearSelect.value = this.currentLeftYear;
                        if (this.rightMonthName) this.rightMonthName.textContent = monthNames[rightMY.month];
                        if (this.rightYearSelect) this.rightYearSelect.value = rightMY.year;
                        if (this.leftDaysContainer) this._populateDaysContainer(this.leftDaysContainer, this.currentLeftMonth, this.currentLeftYear);
                        if (this.rightDaysContainer) this._populateDaysContainer(this.rightDaysContainer, rightMY.month, rightMY.year);
                        this._updatePresetSelectionVisuals();
                    }
                }
            });
            
            input.addEventListener('blur', () => {
                const parsed = parseDate(input.value);
                if (!parsed) {
                    if (isStart) {
                        input.value = this._formatDateDisplay(this.tempStartDate);
                    } else {
                        input.value = this._formatDateDisplay(this.tempEndDate);
                    }
                }
            });
        };

        setupInput(this.startDisplay, true);
        setupInput(this.endDisplay, false);
    }

    _populateYearSelects() {
        if (!this.leftYearSelect || !this.rightYearSelect) return;
        
        this.leftYearSelect.innerHTML = '';
        this.rightYearSelect.innerHTML = '';
        
        const startYear = 2020;
        const endYear = new Date().getFullYear() + 4;
        
        for (let y = startYear; y <= endYear; y++) {
            const optLeft = document.createElement('option');
            optLeft.value = y;
            optLeft.textContent = y;
            this.leftYearSelect.appendChild(optLeft);
            
            const optRight = document.createElement('option');
            optRight.value = y;
            optRight.textContent = y;
            this.rightYearSelect.appendChild(optRight);
        }
        
        this.leftYearSelect.addEventListener('change', () => {
            this._handleYearChange(parseInt(this.leftYearSelect.value, 10), true);
        });
        
        this.rightYearSelect.addEventListener('change', () => {
            this._handleYearChange(parseInt(this.rightYearSelect.value, 10), false);
        });
    }

    _handleYearChange(year, isLeft) {
        if (isLeft) {
            this.currentLeftYear = year;
        } else {
            const rightMY = this._getRightMonthYear();
            const rightMonth = rightMY.month;
            if (rightMonth === 0) {
                this.currentLeftYear = year - 1;
            } else {
                this.currentLeftYear = year;
            }
        }
        this._renderCalendars();
    }

    toggle() {
        if (this.isOpen) {
            this.close();
        } else {
            this.open();
        }
    }

    open() {
        document.querySelectorAll('.custom-dropdown.active').forEach(dd => {
            dd.classList.remove('active');
            dd.querySelector('.custom-dropdown-trigger')?.setAttribute('aria-expanded', 'false');
        });
        
        this.isOpen = true;
        this.container.classList.add('active');
        this.trigger.setAttribute('aria-expanded', 'true');
        
        this.tempStartDate = this.startDate ? new Date(this.startDate) : null;
        this.tempEndDate = this.endDate ? new Date(this.endDate) : null;
        
        const today = new Date();
        if (this.endDate) {
            this.currentLeftMonth = this.endDate.getMonth();
            this.currentLeftYear = this.endDate.getFullYear();
        } else {
            this.currentLeftMonth = today.getMonth();
            this.currentLeftYear = today.getFullYear();
        }
        
        this._renderCalendars();
        
        if (window.innerWidth <= 768) {
            document.body.classList.add('date-picker-open');
        }
    }

    close() {
        this.isOpen = false;
        this.container.classList.remove('active');
        this.trigger.setAttribute('aria-expanded', 'false');
        document.body.classList.remove('date-picker-open');
    }

    _handleCancel() {
        this.tempStartDate = this.startDate ? new Date(this.startDate) : null;
        this.tempEndDate = this.endDate ? new Date(this.endDate) : null;
        this.close();
    }

    _handleApply() {
        this.startDate = this.tempStartDate;
        this.endDate = this.tempEndDate;
        
        this._updateTriggerLabel();
        this.close();
        
        const startStr = this._getDateString(this.startDate);
        const endStr = this._getDateString(this.endDate);
        if (this.onChange) {
            this.onChange(startStr, endStr);
        }
    }
    
    _getDateString(date) {
        if (!date) return '';
        const y = date.getFullYear();
        const m = String(date.getMonth() + 1).padStart(2, '0');
        const d = String(date.getDate()).padStart(2, '0');
        return `${y}-${m}-${d}`;
    }
}
