'use strict';

/**
 * Port dari packages/designer/src/migrators/backend_payload_migrator.rs.
 *
 * Orchestrator utama konversi payload backend (RESTForge / RDF) menjadi
 * frontend payload designer (UDF). Menggabungkan output sql-parser +
 * field-type-resolver + label-generator untuk menghasilkan frontend payload
 * deterministic.
 */

const { parseDatatablesQuery } = require('./sql-parser');
const { FieldTypeResolver } = require('./field-type-resolver');
const { snakeToKebab, snakeToTitle } = require('./naming');

const DEFAULT_ICON = 'file-text';
const ICON_MAP = {
    contact: 'users',
    customer: 'users',
    user: 'users',
    supplier: 'truck',
    vendor: 'truck',
    category: 'tag',
    item: 'package',
    product: 'package',
    stock: 'clipboard',
    inventory: 'clipboard',
    warehouse: 'building',
    order: 'shopping-cart',
    invoice: 'file-text',
    city: 'map-pin',
    country: 'globe',
    department: 'briefcase',
    employee: 'user'
};

function detectIcon(tableName) {
    const lower = String(tableName || '').toLowerCase();
    for (const keyword of Object.keys(ICON_MAP)) {
        if (lower.includes(keyword)) return ICON_MAP[keyword];
    }
    return DEFAULT_ICON;
}

function detectDisplayField(resolvedFields, primaryKey) {
    for (const rf of resolvedFields) {
        if (rf.name.endsWith('_name') || rf.name === 'name') return rf.name;
    }
    for (const rf of resolvedFields) {
        if (rf.name.endsWith('_code') || rf.name === 'code') return rf.name;
    }
    for (const rf of resolvedFields) {
        if ((rf.fieldType === 'text' || rf.fieldType === 'textarea') && rf.name !== primaryKey) {
            return rf.name;
        }
    }
    if (resolvedFields.length > 0) return resolvedFields[0].name;
    return '';
}

function convertSinglePage(backend) {
    const warnings = [];
    const tableName = String(backend.tableName || '');
    const primaryKey = String(backend.primaryKey || '');
    const fieldNames = Array.isArray(backend.fieldName) ? backend.fieldName.filter(n => typeof n === 'string') : [];
    const datatablesQuery = String(backend.datatablesQuery || '');
    const datatablesWhere = Array.isArray(backend.datatablesWhere) ? backend.datatablesWhere : [];
    const fieldValidations = Array.isArray(backend.fieldValidation) ? backend.fieldValidation : [];

    const cleanTable = tableName.split('.').pop() || tableName;
    const parsedQuery = parseDatatablesQuery(datatablesQuery);
    const resolver = new FieldTypeResolver(fieldValidations, parsedQuery, primaryKey);

    const resolvedFields = fieldNames
        .map(name => resolver.resolve(name))
        .filter(rf => !rf.skip);

    const displayField = detectDisplayField(resolvedFields, primaryKey);

    const hasSearch = datatablesWhere.length > 0
        && datatablesWhere.some(w => typeof w === 'string' && w !== 'all');
    const hasStatusFilter = resolvedFields.some(rf => rf.name === 'is_active' || rf.name === 'status');

    const features = {
        enableSearch: hasSearch,
        fieldLayout: 'vertical'
    };

    if (hasStatusFilter) {
        features.enableStatusFilter = true;
        for (const rf of resolvedFields) {
            if ((rf.name === 'is_active' || rf.name === 'status') && rf.fieldType === 'checkbox') {
                const cbt = (rf.extra && rf.extra.checkboxText) || {};
                const checked = typeof cbt.checked === 'string' ? cbt.checked : 'Active';
                const unchecked = typeof cbt.unchecked === 'string' ? cbt.unchecked : 'Inactive';
                features.statusFilter = {
                    field: rf.name,
                    label: rf.label,
                    options: [
                        { value: 'true', text: checked },
                        { value: 'false', text: unchecked }
                    ]
                };
                break;
            }
        }
    }

    const fieldsArray = [];
    for (const rf of resolvedFields) {
        const fieldObj = { name: rf.name, label: rf.label, type: rf.fieldType };
        if (rf.required) fieldObj.required = true;
        if (rf.inTable) {
            fieldObj.inTable = true;
            if (rf.tableOrder !== null && rf.tableOrder !== undefined) {
                fieldObj.tableOrder = rf.tableOrder;
            }
        }
        if (rf.tableField) fieldObj.tableField = rf.tableField;
        if (rf.defaultValue !== undefined) fieldObj.defaultValue = rf.defaultValue;
        if (rf.extra && typeof rf.extra === 'object') {
            for (const [key, val] of Object.entries(rf.extra)) {
                fieldObj[key] = val;
            }
        }
        fieldsArray.push(fieldObj);
    }

    if (backend.masterDetail !== undefined && backend.masterDetail !== null) {
        warnings.push(`${cleanTable}: masterDetail is detected — detail tables are not yet supported, only header fields will be converted`);
    }

    const pageId = snakeToKebab(cleanTable);
    const pageTitle = snakeToTitle(cleanTable);

    const page = {
        pageId,
        pageTitle,
        pageSubtitle: `Manage ${pageTitle.toLowerCase()} data`,
        pageIcon: detectIcon(cleanTable),
        apiPath: pageId,
        primaryKey,
        displayField,
        features,
        fields: fieldsArray
    };

    return { page, warnings };
}

function migrate(backendPayloads, appName, appCode, plugin, apiBaseUrl, port) {
    if (!Array.isArray(backendPayloads) || backendPayloads.length === 0) {
        return {
            success: false,
            payload: null,
            pageResults: [],
            errors: ['No backend payload was provided'],
            warnings: []
        };
    }

    const pages = [];
    const pageResults = [];
    const allWarnings = [];

    for (let i = 0; i < backendPayloads.length; i++) {
        const backend = backendPayloads[i];
        const tableName = (backend && typeof backend.tableName === 'string') ? backend.tableName : '';
        if (!tableName) {
            allWarnings.push(`Payload #${i + 1}: tableName is not defined, skipped`);
            continue;
        }

        const { page, warnings } = convertSinglePage(backend);

        const fieldCount = Array.isArray(page.fields) ? page.fields.length : 0;
        const tableColCount = Array.isArray(page.fields)
            ? page.fields.filter(f => f.inTable === true).length
            : 0;

        pages.push(page);
        pageResults.push({
            pageId: page.pageId,
            fieldCount,
            tableColCount,
            warnings: warnings.slice()
        });
        for (const w of warnings) allWarnings.push(w);
    }

    if (pages.length === 0) {
        return {
            success: false,
            payload: null,
            pageResults: [],
            errors: ['No page was successfully converted'],
            warnings: allWarnings
        };
    }

    const payload = {
        appConfig: {
            appName,
            appCode,
            plugin,
            apiBaseUrl,
            port
        },
        pages
    };

    return {
        success: true,
        payload,
        pageResults,
        errors: [],
        warnings: allWarnings
    };
}

module.exports = { migrate, convertSinglePage, detectIcon, detectDisplayField };
