"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrate = migrate;
const ts = require("typescript");
const ast_utils_1 = require("../../utils/ast-utils");
const html_utils_1 = require("../../utils/html-utils");
const workspace_utils_1 = require("../../utils/workspace-utils");
const UNSUPPORTED_ATTRS = ['inline', 'touchUI', 'showWeek', 'numberOfMonths', 'variant', 'size', 'fluid'];
const SILENT_REMOVE_ATTRS = ['appendTo', 'dataType', 'sDatepickerNoPeriodTab'];
const WARN_EVENTS = ['(onClear)', '(onClickOutside)'];
const PRIMENG_DATEPICKER_MODULES = ['DatePickerModule', 'CalendarModule'];
const REQUIRED_STYLE = 'node_modules/@seniorsistemas/angular-components/styles.css';
function migrate() {
    return (tree, context) => {
        (0, workspace_utils_1.ensureAngularJsonStyle)(tree, REQUIRED_STYLE, context);
        tree.visit((path) => {
            if (path.includes('/node_modules/'))
                return;
            if (path.endsWith('.html')) {
                migrateTemplate(tree, path, context);
            }
            else if (path.endsWith('.ts')) {
                migrateTypeScript(tree, path, context);
            }
        });
    };
}
function migrateTemplate(tree, path, context) {
    const content = tree.readText(path);
    if (!content.includes('p-datepicker'))
        return;
    let updated = content;
    // Warn about unsupported events before removing them
    for (const event of WARN_EVENTS) {
        if (updated.includes(event)) {
            context.logger.warn(`${path}: ${event} não tem equivalente no s-datepicker e foi removido. Remova o handler manualmente.`);
            updated = (0, html_utils_1.removeHtmlAttribute)(updated, event);
        }
    }
    // Warn about ng-template inside p-datepicker (custom templates not migrated)
    if (/<p-datepicker[^>]*>[\s\S]*?<ng-template/.test(updated)) {
        context.logger.warn(`${path}: ng-template dentro de p-datepicker não é migrado automaticamente. Revise manualmente.`);
    }
    // Warn about (onShow) if handler uses $event
    if (/\(onShow\)\s*=\s*"[^"]*\$event/.test(updated)) {
        context.logger.warn(`${path}: (onShow) agora emite void (sem HTMLElement). Remova o uso de $event no handler.`);
    }
    // Warn about (onSelect) with typed $event usage (common pattern)
    if (/\(onSelect\)\s*=\s*"[^"]*\$event/.test(updated)) {
        context.logger.warn(`${path}: (selected) agora emite Date | DateRange | Date[] | null. Verifique o tipo do handler se usar $event tipado.`);
    }
    // Warn about range value array access (value[0] / value[1] pattern)
    if (updated.includes('[0]') || updated.includes('[1]')) {
        context.logger.warn(`${path}: Verifique acessos a value[0]/value[1] para mode="range" — o s-datepicker retorna { start, end } em vez de array.`);
    }
    // Warn about unsupported attributes
    for (const attr of UNSUPPORTED_ATTRS) {
        const pattern = new RegExp(`\\[?${attr}\\]?\\s*=`, 'g');
        if (pattern.test(updated)) {
            context.logger.warn(`${path}: Atributo "${attr}" não é suportado pelo s-datepicker e foi removido.`);
        }
    }
    // 1. Handle showTime + view combos → mode="datetime"
    updated = updated.replace(/(<p-datepicker\b[^>]*?)\[showTime\]="true"([^>]*?)view="date"([^>]*?>)/gs, '$1mode="datetime"$2$3');
    updated = updated.replace(/(<p-datepicker\b[^>]*?)view="date"([^>]*?)\[showTime\]="true"([^>]*?>)/gs, '$1mode="datetime"$2$3');
    // showTime without explicit view also becomes datetime
    updated = updated.replace(/(<p-datepicker\b[^>]*?)\[showTime\]="true"([^>]*?>)/gs, '$1mode="datetime"$2');
    // 2. timeOnly → mode="time"
    updated = updated.replace(/(<p-datepicker\b[^>]*?)\[timeOnly\]="true"([^>]*?>)/gs, '$1mode="time"$2');
    // 3. selectionMode="range" / [selectionMode]="'range'" → mode="range"
    updated = updated.replace(/\[selectionMode\]="'range'"/g, 'mode="range"');
    updated = updated.replace(/selectionMode="range"/g, 'mode="range"');
    // 4. selectionMode="multiple" / [selectionMode]="'multiple'" → selectionMode="multiple" (stays, no-op for static)
    updated = updated.replace(/\[selectionMode\]="'multiple'"/g, 'selectionMode="multiple"');
    // 5. view="month" / view="year" → mode="..."
    updated = updated.replace(/\bview="month"/g, 'mode="month"');
    updated = updated.replace(/\bview="year"/g, 'mode="year"');
    // view="date" → remove (it's the default)
    updated = updated.replace(/\s*\bview="date"/g, '');
    // 6. minDate / maxDate → min / max
    updated = updated.replace(/\[minDate\]/g, '[min]');
    updated = updated.replace(/\bminDate=/g, 'min=');
    updated = updated.replace(/\[maxDate\]/g, '[max]');
    updated = updated.replace(/\bmaxDate=/g, 'max=');
    // 7. stepMinute → minuteStep
    updated = updated.replace(/\[stepMinute\]/g, '[minuteStep]');
    updated = updated.replace(/\bstepMinute=/g, 'minuteStep=');
    // 8. Event renames
    updated = updated.replace(/\(onFocus\)/g, '(focused)');
    updated = updated.replace(/\(onBlur\)/g, '(blurred)');
    updated = updated.replace(/\(onSelect\)/g, '(selected)');
    updated = updated.replace(/\(onInput\)/g, '(valueInput)');
    updated = updated.replace(/\(onClose\)/g, '(closed)');
    updated = updated.replace(/\(onShow\)/g, '(show)');
    updated = updated.replace(/\(onTodayClick\)/g, '(todayClick)');
    updated = updated.replace(/\(onClearClick\)/g, '(clearClick)');
    updated = updated.replace(/\(onMonthChange\)/g, '(monthChange)');
    updated = updated.replace(/\(onYearChange\)/g, '(yearChange)');
    // 9. Remove attributes without equivalent (silent)
    for (const attr of SILENT_REMOVE_ATTRS) {
        updated = (0, html_utils_1.removeHtmlAttribute)(updated, attr);
    }
    // 10. Remove unsupported attributes (already warned above)
    for (const attr of UNSUPPORTED_ATTRS) {
        updated = (0, html_utils_1.removeHtmlAttribute)(updated, attr);
    }
    // 11. Rename tag (opening and closing)
    updated = updated.replace(/<p-datepicker\b/g, '<s-datepicker');
    updated = updated.replace(/<\/p-datepicker>/g, '</s-datepicker>');
    if (updated !== content) {
        tree.overwrite(path, updated);
    }
}
function migrateTypeScript(tree, path, context) {
    const content = tree.readText(path);
    if (!PRIMENG_DATEPICKER_MODULES.some((m) => content.includes(m)))
        return;
    const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
    const { changes: importChanges } = (0, ast_utils_1.buildRemoveNamedImportsChanges)(sourceFile, PRIMENG_DATEPICKER_MODULES, 'primeng');
    const decoratorChanges = [
        ...ast_utils_1.ngModule.replaceInImports(sourceFile, PRIMENG_DATEPICKER_MODULES, 'DatepickerComponent'),
        ...ast_utils_1.ngModule.replaceInExports(sourceFile, PRIMENG_DATEPICKER_MODULES, 'DatepickerComponent'),
        ...ast_utils_1.ngComponent.replaceInImports(sourceFile, PRIMENG_DATEPICKER_MODULES, 'DatepickerComponent'),
    ];
    if (importChanges.length === 0 && decoratorChanges.length === 0)
        return;
    if (/\[\s*0\s*\]|\[\s*1\s*\]/.test(content) && /range/i.test(content)) {
        context.logger.warn(`${path}: Possível acesso a value[0]/value[1] em modo range detectado. O s-datepicker retorna { start, end } — revise manualmente.`);
    }
    let updated = (0, ast_utils_1.applyChanges)(content, [...importChanges, ...decoratorChanges]);
    updated = updated.replace(/\n\n+/g, '\n\n');
    updated = (0, ast_utils_1.insertImportStatement)(updated, 'DatepickerComponent', '@seniorsistemas/angular-components/datepicker');
    if (updated !== content) {
        tree.overwrite(path, updated);
    }
}
//# sourceMappingURL=index.js.map