import React, { useMemo, useState, useEffect, useCallback, useRef } from 'react';
import { useUser } from '../../../utilities/auth/useUser';
import { useTenant } from '../../../utilities/tenant/useTenant';
import { useHistory, useLocation } from 'react-router-dom';
import { useSnackbar } from 'notistack';
import { CustomMenuPage } from '../../../menuPage';
import { useTranslation } from 'react-i18next';
import { apiMutate } from '../../../utilities';
import { ConfigService } from '../../../configService';
import { SearchMethodUdpGrid } from '../../../UI/templates/newGrid';
import { LoadingIndicator } from '../../../UI/loading/LoadingIndicator';
import { UdpPageEnums } from '../../../enums';
import { StatusCellRenderer } from '../../../UI/templates/ui/renderers';
import { SqlFilterOperators } from '../../../enums/aggridEnums';
import { SideSheet } from '../../../UI/surfaces/SideSheet';
import { Autocomplete } from '@material-ui/lab';
import { TextField, FormControlLabel, Switch } from '@material-ui/core';
import { PageLoading } from '../../../UI';
import { parseSearchParamsIntoFilterObjects } from '../../../utilities/search';
// ============================================================================
// Grid Ids Enums
// ============================================================================
const UdpFormsSubmissionGridIds = Object.freeze({
    ResponderId: '5C4A93B6-6C25-4236-ABCA-2E23DC6540B5',
    ManagerId: '15F165D1-82CD-4775-9A35-FF2153058240'
});
// ============================================================================
// Submission status enum
// Used to map numeric submission status values returned from the backend
// ============================================================================
const UdpFormsSubmissionStatusEnum = Object.freeze({
    InProgress: 1,
    Submitted: 2,
    Created: 3
});
// ============================================================================
// Date formatter helper
// Normalizes backend date strings and formats them for display
// Handles both ISO strings and "YYYY-MM-DD HH:mm:ss.sss" formats
// ============================================================================
const formatDateTime = (dateString) => {
    let normalizedDateString = dateString;
    // Check if the string is in the 'YYYY-MM-DD HH:mm:ss.sss' format
    // (i.e., contains a space instead of 'T').
    // If the input is already ISO (e.g. '2025-12-10T20:23:23.055Z'),
    // it passes straight through.
    // This format is assumed to be missing timezone info and treated as UTC.
    if (dateString.includes(' ')) {
        // Replace the space with 'T' to normalize to ISO-like format
        normalizedDateString = dateString.replace(' ', 'T');
    }
    // Ensure UTC timezone is explicitly specified
    if (!dateString.toUpperCase().endsWith('Z')) {
        normalizedDateString = normalizedDateString + 'Z';
    }
    const date = new Date(normalizedDateString);
    // Localized, user-friendly date/time display
    return date.toLocaleString(undefined, {
        year: 'numeric',
        month: 'short',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
        hour12: true
    });
};
const toUtcIsoAtLocalEndOfDay = (yyyyMmDd) => {
    if (!yyyyMmDd)
        return null;
    const [y, m, d] = String(yyyyMmDd)
        .split('-')
        .map((x) => Number(x));
    if (!y || !m || !d)
        return null;
    // local time end-of-day (23:59:59.000), then serialize as UTC ISO
    const local = new Date(y, m - 1, d, 23, 59, 59, 0);
    return local.toISOString();
};
// ============================================================================
// FormTemplateOverrides helpers
// `formSubmission_Data` may be a JSON object or a JSON string.
// If `Data.FormTemplateOverrides.FormName` / `FormDescription` are populated,
// they should override the displayed `form_Name` / `form_Description`.
// ============================================================================
const tryParseJsonObject = (value) => {
    if (!value)
        return null;
    if (typeof value === 'object')
        return value;
    if (typeof value !== 'string')
        return null;
    try {
        return JSON.parse(value);
    }
    catch (_a) {
        return null;
    }
};
const hasNonWhitespaceText = (v) => typeof v === 'string' && v.trim().length > 0;
const applySubmissionTemplateOverrides = (submissionRow) => {
    if (!submissionRow)
        return submissionRow;
    const dataObj = tryParseJsonObject(submissionRow.formSubmission_Data);
    const overrides = dataObj === null || dataObj === void 0 ? void 0 : dataObj.FormTemplateOverrides;
    if (!overrides)
        return submissionRow;
    const newSubmissionRow = Object.assign({}, submissionRow);
    if (hasNonWhitespaceText(overrides.FormName)) {
        newSubmissionRow.form_Name = overrides.FormName.trim();
    }
    if (hasNonWhitespaceText(overrides.FormDescription)) {
        newSubmissionRow.form_Description = overrides.FormDescription.trim();
    }
    return newSubmissionRow;
};
const formatDateForFilename = (dateString) => {
    if (!dateString)
        return '';
    let normalizedDateString = dateString;
    if (typeof normalizedDateString === 'string' && normalizedDateString.includes(' ')) {
        normalizedDateString = normalizedDateString.replace(' ', 'T');
    }
    if (typeof normalizedDateString === 'string' &&
        !normalizedDateString.toUpperCase().endsWith('Z')) {
        normalizedDateString = normalizedDateString + 'Z';
    }
    const date = new Date(normalizedDateString);
    if (Number.isNaN(date.getTime()))
        return '';
    return date.toLocaleDateString(undefined, {
        year: 'numeric',
        month: 'long',
        day: '2-digit'
    });
};
const sanitizeFilenamePart = (value) => String(value !== null && value !== void 0 ? value : '')
    // Windows file name chars: \ / : * ? " < > |
    .replace(/[\\/:*?"<>|]/g, '')
    .replace(/\s+/g, ' ')
    .trim();
const getSubmissionDisplayFormName = (row, t) => {
    var _a;
    const dataObj = tryParseJsonObject(row === null || row === void 0 ? void 0 : row.formSubmission_Data);
    const overrideName = (_a = dataObj === null || dataObj === void 0 ? void 0 : dataObj.FormTemplateOverrides) === null || _a === void 0 ? void 0 : _a.FormName;
    const baseName = row === null || row === void 0 ? void 0 : row.form_Name;
    const name = hasNonWhitespaceText(overrideName)
        ? overrideName.trim()
        : hasNonWhitespaceText(baseName)
            ? baseName.trim()
            : t('Untitled Form');
    return name;
};
const getBrowserTimeZone = () => {
    try {
        return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
    }
    catch (_a) {
        return 'UTC';
    }
};
// ============================================================================
// URL filter field → ag-Grid filter configuration mapping
// Used when converting URL search params into ag-Grid filter models
// ============================================================================
const filterConfigByUrlField = {
    form_name: { agGridField: 'form_Name', filterType: 'text' },
    formsubmission_formid: {
        agGridField: 'formSubmission_FormId',
        filterType: 'text'
    },
    formsubmission_formversion: {
        agGridField: 'formSubmission_FormVersion',
        filterType: 'number'
    },
    form_description: { agGridField: 'form_Description', filterType: 'text' },
    formsubmission_userdisplayname: {
        agGridField: 'formSubmission_UserDisplayName',
        filterType: 'text'
    },
    formsubmission_status: {
        agGridField: 'formSubmission_Status',
        filterType: 'number'
    },
    formsubmission_initialcreatedon: {
        agGridField: 'formSubmission_InitialCreatedOn',
        filterType: 'date'
    },
    formsubmission_lastmodifiedon: {
        agGridField: 'formSubmission_LastModifiedOn',
        filterType: 'date'
    },
    formsubmission_submittedon: {
        agGridField: 'formSubmission_SubmittedOn',
        filterType: 'date'
    },
    formsubmission_duedate: {
        agGridField: 'formSubmission_DueDate',
        filterType: 'date'
    },
    formsubmission_isoverdue: {
        agGridField: 'formSubmission_IsOverdue',
        filterType: 'text'
    }
};
/**
 * Maps your internal filter object structure (from URL processing)
 * to the ag-Grid Filter Model structure.
 * @param {Array<{searchField: string, searchOperator: number, searchValue: string}>} filterObjects
 * @returns {object} ag-Grid Filter Model
 */
const mapUrlFiltersToAgGridModel = (filterObjects) => {
    if (!filterObjects || filterObjects.length === 0) {
        return null;
    }
    const agGridModel = {};
    filterObjects.forEach((filter) => {
        const { searchField, searchOperator, searchValue } = filter;
        const searchKey = searchField.toLocaleLowerCase();
        const config = filterConfigByUrlField[searchKey];
        if (!config) {
            console.warn(`No configuration found for URL filter field: ${searchField}. Filter ignored.`);
            return;
        }
        const agGridField = config.agGridField;
        const filterType = config.filterType;
        let type = 'equals';
        switch (searchOperator) {
            case SqlFilterOperators.EQUALS:
                type = 'equals';
                break;
            case SqlFilterOperators.NOT_EQUALS:
                type = 'notEqual';
                break;
            case SqlFilterOperators.GREATER_THAN:
                type = 'greaterThan';
                break;
            case SqlFilterOperators.LESS_THAN:
                type = 'lessThan';
                break;
            case SqlFilterOperators.LIKE:
                type = 'contains';
                break;
            default:
                type = 'equals';
        }
        let filterValue = searchValue;
        if (!filterValue ||
            filterValue.toLowerCase() === 'undefined' ||
            filterValue.toLowerCase() === 'null') {
            console.warn(`Skipping filter for ${agGridField} due to invalid value: ${searchValue}`);
            return;
        }
        if (filterType == 'date') {
            agGridModel[agGridField] = {
                filterType,
                type,
                dateFrom: filterValue
            };
        }
        else if (filterType == 'text' &&
            agGridField.toLocaleLowerCase() == 'formsubmission_isoverdue') {
            agGridModel[agGridField] = {
                filterType,
                type: filterValue
            };
        }
        else {
            agGridModel[agGridField] = {
                filterType,
                type,
                filter: filterValue
            };
        }
    });
    return agGridModel;
};
// ============================================================================
// Helper for CustomMenuPage to parse form submission ID and version from node ID
// ============================================================================
const parseIdAndVersion = (input) => {
    const formSubmissionId = input.replace(/^form-submission-/, '');
    // Check for "all forms" special case
    if (formSubmissionId.includes('all-forms-key')) {
        return null;
    }
    return formSubmissionId;
};
// ============================================================================
// Maps a submission status enum value to a human-readable status label
// Used in grid cell renderer
// ============================================================================
const getSubmissionStatusLabel = (node) => {
    var _a;
    const formStatus = (_a = node === null || node === void 0 ? void 0 : node.data) === null || _a === void 0 ? void 0 : _a.formSubmission_Status;
    switch (formStatus) {
        case UdpFormsSubmissionStatusEnum.InProgress:
            return 'InProgress';
        case UdpFormsSubmissionStatusEnum.Created:
            return 'Created';
        case UdpFormsSubmissionStatusEnum.Submitted:
            return 'Submitted';
        default:
            return '';
    }
};
// ============================================================================
// Maps overdue flag to a display label
// Used in grid cell renderer
// ============================================================================
const getOverdueStatusLabel = (node) => {
    var _a;
    const overdueStatus = (_a = node === null || node === void 0 ? void 0 : node.data) === null || _a === void 0 ? void 0 : _a.formSubmission_IsOverdue;
    switch (overdueStatus) {
        case true:
            return 'Overdue';
        default:
            return '';
    }
};
// ============================================================================
// Filters form submissions by tenant ID
// ============================================================================
const filterSubmissionByTenantId = (submissions, tenantId) => {
    return submissions.filter((submission) => submission.form_TenantId === tenantId);
};
// ============================================================================
// Map of status labels to status types
// Used in grid configs
// ============================================================================
const gridFunctions = [
    { name: 'agGridSizeColumnsToFit' },
    { name: 'agGridAutoSizeColumns' },
    { name: 'agGridResetColumns' },
    { name: 'agGridHideShowColumns' },
    { name: 'agGridExport' },
    { name: 'openSavedViews' },
];
// ============================================================================
// Map of status labels to status types
// Used in grid configs
// ============================================================================
const statusMappingConfig = {
    Created: 'info',
    InProgress: 'warning',
    Submitted: 'success',
    Overdue: 'error'
};
// ============================================================================
// Map of status labels to status types
// Grid options config
// ============================================================================
const defaultGridOptions = {
    pagination: true,
    defaultColDef: {
        sortable: true,
        filter: true,
        resizable: true
    }
};
export const UdpFormsSubmissionGrid = ({ isManagerMode = false, generic1 = undefined, generic2 = undefined, generic3 = undefined, formsRendererUrlPath = undefined, allFormTitle = undefined, menuTitle = undefined, onSideSheetPrimaryAction = undefined, enableDownloadPdfAction = true, paginationAutoPageSize = true }) => {
    var _a;
    const user = useUser();
    const tenant = useTenant();
    const history = useHistory();
    const location = useLocation();
    const { t } = useTranslation();
    const { enqueueSnackbar, closeSnackbar } = useSnackbar();
    // Component states
    const [innerMenuItemList, setInnerMenuItemList] = useState([]);
    const [formSubmissionViewDataRaw, setFormSubmissionViewDataRaw] = useState([]);
    const [formDataRaw, setFormDataRaw] = useState([]);
    const [isSidesheetOpen, setIsSidesheetOpen] = useState(false);
    const [selectedUdpFormInSideSheet, setSelectedUdpFormInSideSheet] = useState({});
    const [formSubmissionUrlSearchObjs, setFormSubmissionUrlSearchObjs] = useState([]);
    const [gridApi, setGridApi] = useState(null);
    const handleGridApiCallback = useCallback((api) => { setGridApi(api); }, []);
    const [containsDueDate, setContainsDueDate] = useState(false);
    const [dueDateValue, setDueDateValue] = useState(null);
    const [isPdfDownloadInProgress, setIsPdfDownloadInProgress] = useState(false);
    const isPdfDownloadInProgressRef = useRef(false);
    const initialFilterModel = useMemo(() => {
        return mapUrlFiltersToAgGridModel(formSubmissionUrlSearchObjs);
    }, [formSubmissionUrlSearchObjs]);
    const gridOptions = useMemo(() => {
        return Object.assign(Object.assign({}, defaultGridOptions), { paginationAutoPageSize, overlayLoadingTemplate: `<UdpText variant="body1">Generating PDF...</UdpText>` });
    }, [paginationAutoPageSize, t]);
    useEffect(() => {
        if (gridApi && initialFilterModel) {
            gridApi.setFilterModel(initialFilterModel);
            gridApi.onFilterChanged();
        }
    }, [gridApi, initialFilterModel]);
    useEffect(() => {
        if (!gridApi)
            return;
        gridApi.refreshCells({ force: true, columns: ['actions'] });
    }, [gridApi, isPdfDownloadInProgress]);
    useEffect(() => {
        if (!(gridApi === null || gridApi === void 0 ? void 0 : gridApi.toggleLoadingOverlay))
            return;
        // Show a blocking loading mask so users get immediate visual feedback
        // and cannot trigger additional actions while a PDF is being generated.
        gridApi.toggleLoadingOverlay(isPdfDownloadInProgress);
    }, [gridApi, isPdfDownloadInProgress]);
    const consolidateAndSortFormsByFormId = useCallback((forms, submissions = []) => {
        const resultMap = new Map();
        for (const item of forms) {
            const { id: formId, version: formVersion, name: formName, description: formDescription, initialCreatedOn: initialCreatedOn } = item;
            if (!formId || formVersion == null)
                continue;
            const key = String(formId);
            const existing = resultMap.get(key);
            // normalize version and timestamp
            const versionNum = Number(formVersion) || 0;
            const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;
            // robust comparison (coerce to string)
            const submissionCount = (submissions || []).filter((sub) => String(sub === null || sub === void 0 ? void 0 : sub.formSubmission_FormId) === key).length;
            if (!existing) {
                resultMap.set(key, {
                    id: key,
                    formId,
                    formVersion: versionNum,
                    name: formName || t('Untitled Form'),
                    submissionCount,
                    description: formDescription || '',
                    mostRecentCreatedOn: ts
                });
            }
            else {
                // keep metadata (name/description/formVersion) from the highest version seen
                if (versionNum > (existing.formVersion || 0)) {
                    existing.formVersion = versionNum;
                    if (formName)
                        existing.name = formName;
                    if (formDescription)
                        existing.description = formDescription;
                }
            }
        }
        const sortedOptions = Array.from(resultMap.values()).sort((a, b) => b.name.localeCompare(a.name));
        return sortedOptions;
    }, [t]);
    const consolidateAndSortFormSubmissionsByFormId = useCallback((submissions) => {
        const resultMap = new Map();
        for (const item of submissions) {
            const { formSubmission_FormId: formId, formSubmission_FormVersion: formVersion, form_Name: formName, form_Description: formDescription, formSubmission_InitialCreatedOn: initialCreatedOn } = item;
            if (!formId || formVersion == null)
                continue;
            const key = `${formId}`;
            const existing = resultMap.get(key);
            // normalize version and timestamp
            const versionNum = Number(formVersion) || 0;
            const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;
            if (!existing) {
                resultMap.set(key, {
                    id: key,
                    formId,
                    formVersion: versionNum,
                    name: formName || t('Untitled Form'),
                    submissionCount: 1,
                    description: formDescription || '',
                    mostRecentCreatedOn: ts
                });
            }
            else {
                existing.submissionCount += 1;
                existing.mostRecentCreatedOn = Math.max(existing.mostRecentCreatedOn || 0, ts);
                // keep metadata (name/description/formVersion) from the highest version seen
                if (versionNum > (existing.formVersion || 0)) {
                    existing.formVersion = versionNum;
                    if (formName)
                        existing.name = formName;
                    if (formDescription)
                        existing.description = formDescription;
                }
            }
        }
        const sortedOptions = Array.from(resultMap.values()).sort((a, b) => b.mostRecentCreatedOn - a.mostRecentCreatedOn);
        return sortedOptions;
    }, [t]);
    const fetchForms = useCallback(async () => {
        var _a;
        try {
            if (!((_a = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) === null || _a === void 0 ? void 0 : _a.tenantId))
                return;
            const filterElements = [];
            filterElements.push({
                searchField: 'tenantId',
                searchOperator: '=',
                searchValue: tenant.activeTenant.tenantId
            });
            const formResponse = await apiMutate(ConfigService.productV1ApiUrl, `UdpForm/search`, {
                method: 'POST',
                data: {
                    eagerLoad: false,
                    getAll: true,
                    filterElements
                }
            }, {});
            const forms = (formResponse === null || formResponse === void 0 ? void 0 : formResponse.data.pageList) || [];
            setFormDataRaw(forms);
        }
        catch (e) {
            console.error('fetchForms error:', e);
        }
    }, [user, tenant, consolidateAndSortFormSubmissionsByFormId]);
    const getSearchMethodConfig = useCallback((formId) => {
        var _a, _b;
        if (!((_a = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) === null || _a === void 0 ? void 0 : _a.tenantId))
            return;
        const filterElements = [];
        if (!isManagerMode) {
            filterElements.push({
                searchField: 'formSubmission_unityUserId',
                searchOperator: '=',
                searchValue: user.id || ''
            });
        }
        if (formId) {
            filterElements.push({
                searchField: 'formSubmission_formId',
                searchOperator: '=',
                searchValue: formId
            });
        }
        if (generic1 !== undefined) {
            filterElements.push({
                searchField: 'formSubmission_generic1',
                searchOperator: '=',
                searchValue: generic1
            });
        }
        if (generic2 !== undefined) {
            filterElements.push({
                searchField: 'formSubmission_generic2',
                searchOperator: '=',
                searchValue: generic2
            });
        }
        if (generic3 !== undefined) {
            filterElements.push({
                searchField: 'formSubmission_generic3',
                searchOperator: '=',
                searchValue: generic3
            });
        }
        filterElements.push({
            searchField: 'form_tenantId',
            searchOperator: '=',
            searchValue: ((_b = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) === null || _b === void 0 ? void 0 : _b.tenantId) || ''
        });
        const orderElements = [
            {
                sortColumn: 'formSubmission_InitialCreatedOn',
                sortDirection: 'DESC'
            }
        ];
        return {
            requestUrl: `${ConfigService.productV1ApiUrl}/UdpFormWithSubmissionsView/search`,
            customSearchObject: {
                eagerLoad: false,
                filterElements,
                orderElements
            }
            // logicalSearchOperator: 1,
            // groupingType: '',
            // groupProperty: [],
            // groupOperationList: [],
            // type: 'advanced',
            // pageNumber: 1,
            // pageSize: 20,
        };
    }, [user, isManagerMode, tenant, generic1, generic2, generic3]);
    const generateFormRendererUrlPathUsingFormIdAndFormVersion = useCallback((formId, formVersion) => {
        const baseRoute = formsRendererUrlPath
            ? formsRendererUrlPath
            : 'page/' + UdpPageEnums.Udp_Forms_Renderer_Page_Private;
        return `${baseRoute}?udpf_formId=${encodeURIComponent(formId)}&udpf_formVersion=${encodeURIComponent(formVersion)}`;
    }, [formsRendererUrlPath]);
    const generateFormRendererUrlPathUsingSubmissionId = useCallback((submissionId) => {
        const baseRoute = formsRendererUrlPath
            ? formsRendererUrlPath
            : 'page/' + UdpPageEnums.Udp_Forms_Renderer_Page_Private;
        return `${baseRoute}?udpf_submissionId=${encodeURIComponent(submissionId)}`;
    }, [formsRendererUrlPath]);
    const getGridHeaderConfig = useCallback((formId, formVersion, formTitle) => {
        const config = {
            title: formTitle
        };
        if (!isManagerMode) {
            config.primaryActionButton = {
                label: t('Submit New Form'),
                onClick: () => {
                    if (formId && formVersion) {
                        setSelectedUdpFormInSideSheet({ value: `${formId}|${formVersion}`, label: formTitle });
                    }
                    setIsSidesheetOpen(true);
                }
            };
        }
        return config;
    }, [history, t, isManagerMode]);
    const columnDefs = [
        { headerName: 'Form ID', field: 'formSubmission_FormId', hide: true },
        {
            headerName: t('Name'),
            field: 'form_Name',
            type: 'text',
            sortable: true,
            valueGetter: (params) => {
                var _a;
                var _b;
                const row = params === null || params === void 0 ? void 0 : params.data;
                if (!row)
                    return '';
                const dataObj = tryParseJsonObject(row.formSubmission_Data);
                const overrideName = (_a = dataObj === null || dataObj === void 0 ? void 0 : dataObj.FormTemplateOverrides) === null || _a === void 0 ? void 0 : _a.FormName;
                if (hasNonWhitespaceText(overrideName))
                    return overrideName.trim();
                return (_b = row.form_Name) !== null && _b !== void 0 ? _b : '';
            }
        },
        {
            headerName: t('Version'),
            field: 'formSubmission_FormVersion',
            type: 'number',
            sortable: true
        },
        {
            headerName: t('Description'),
            field: 'form_Description',
            type: 'text',
            sortable: true,
            hide: true,
            valueGetter: (params) => {
                var _a;
                var _b;
                const row = params === null || params === void 0 ? void 0 : params.data;
                if (!row)
                    return '';
                const dataObj = tryParseJsonObject(row.formSubmission_Data);
                const overrideDescription = (_a = dataObj === null || dataObj === void 0 ? void 0 : dataObj.FormTemplateOverrides) === null || _a === void 0 ? void 0 : _a.FormDescription;
                if (hasNonWhitespaceText(overrideDescription)) {
                    return overrideDescription.trim();
                }
                return (_b = row.form_Description) !== null && _b !== void 0 ? _b : '';
            }
        },
        {
            headerName: t('Submitted By'),
            field: 'formSubmission_UserDisplayName',
            type: 'text',
            sortable: true
        },
        {
            headerName: t('Status'),
            filter: true,
            field: 'formSubmission_Status',
            cellRenderer: 'statusRenderer',
            cellRendererParams: {
                statusMappingConfig: statusMappingConfig,
                getStatusValue: getSubmissionStatusLabel
            }
        },
        {
            headerName: t('Overdue Status'),
            field: 'formSubmission_IsOverdue',
            cellDataType: 'boolean',
            sortable: true,
            cellRenderer: 'statusRenderer',
            cellRendererParams: {
                statusMappingConfig: statusMappingConfig,
                getStatusValue: getOverdueStatusLabel
            }
        },
        {
            headerName: t('Created On'),
            field: 'formSubmission_InitialCreatedOn',
            valueFormatter: (p) => (p.value ? formatDateTime(p.value) : ''),
            sortable: true,
            cellDataType: 'dateTimeString'
        },
        {
            headerName: t('Last Modified On'),
            field: 'formSubmission_LastModifiedOn',
            valueFormatter: (p) => (p.value ? formatDateTime(p.value) : ''),
            sortable: true,
            cellDataType: 'dateTimeString'
        },
        {
            headerName: t('Submitted On'),
            field: 'formSubmission_SubmittedOn',
            valueFormatter: (p) => (p.value ? formatDateTime(p.value) : ''),
            sortable: true,
            cellDataType: 'dateTimeString'
        },
        {
            headerName: t('Due On'),
            field: 'formSubmission_DueDate',
            valueFormatter: (p) => (p.value ? formatDateTime(p.value) : ''),
            sortable: true,
            cellDataType: 'dateTimeString'
        },
        {
            field: 'actions',
            cellRenderer: 'actionsRenderer',
            cellRendererParams: {
                actionList: [
                    {
                        id: 0,
                        iconName: 'view',
                        title: t('Open This Submission'),
                        handleOnClick: (e, params) => {
                            var _a;
                            history.push(`${formsRendererUrlPath
                                ? formsRendererUrlPath
                                : '/page/' + UdpPageEnums.Udp_Forms_Renderer_Page_Private}?udpf_submissionId=${(_a = params === null || params === void 0 ? void 0 : params.data) === null || _a === void 0 ? void 0 : _a.formSubmission_Id}`);
                        }
                    },
                    ...(enableDownloadPdfAction ? [
                        {
                            id: 1,
                            iconName: 'documentPdf',
                            title: t('Download Report'),
                            checkDisabled: () => isPdfDownloadInProgress,
                            // checkDisabled: () => true,
                            handleOnClick: async (e, params) => {
                                // Use a ref lock to avoid rapid-click races before React state re-renders.
                                if (isPdfDownloadInProgressRef.current) {
                                    return;
                                }
                                isPdfDownloadInProgressRef.current = true;
                                setIsPdfDownloadInProgress(true);
                                try {
                                    const row = params === null || params === void 0 ? void 0 : params.data;
                                    const browserTimeZone = getBrowserTimeZone();
                                    const response = await apiMutate(ConfigService.productV1ApiUrl, `udpFormSubmission/${row === null || row === void 0 ? void 0 : row.formSubmission_Id}/report?timeZoneId=${encodeURIComponent(browserTimeZone)}`, {
                                        method: 'GET',
                                        responseType: 'blob'
                                    }, {});
                                    const blob = response.data;
                                    const reportName = getSubmissionDisplayFormName(row, t);
                                    const submissionOwner = (row === null || row === void 0 ? void 0 : row.formSubmission_UserDisplayName) || t('Unknown User');
                                    const isSubmitted = Number(row === null || row === void 0 ? void 0 : row.formSubmission_Status) === UdpFormsSubmissionStatusEnum.Submitted;
                                    const submittedLabel = isSubmitted
                                        ? formatDateForFilename(row === null || row === void 0 ? void 0 : row.formSubmission_SubmittedOn) ||
                                            t('Submitted')
                                        : t('Not Submitted');
                                    const filename = `${sanitizeFilenamePart(reportName)} - ${sanitizeFilenamePart(submissionOwner)} - ${sanitizeFilenamePart(submittedLabel)}.pdf`;
                                    // Create a blob URL and trigger download
                                    const blobUrl = window.URL.createObjectURL(blob);
                                    const link = document.createElement('a');
                                    link.href = blobUrl;
                                    link.download = filename;
                                    document.body.appendChild(link);
                                    link.click();
                                    document.body.removeChild(link);
                                    window.URL.revokeObjectURL(blobUrl);
                                }
                                catch (error) {
                                    console.error('Error downloading report:', error);
                                    enqueueSnackbar(t('Error downloading report'), { variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'center' } });
                                }
                                finally {
                                    isPdfDownloadInProgressRef.current = false;
                                    setIsPdfDownloadInProgress(false);
                                }
                            }
                        }
                    ] : [])
                ]
            }
        }
    ];
    // ============================================================================
    // Side Sheet Helpers and Handlers
    // ============================================================================
    const handleSidesheetPrimaryClick = async () => {
        var _a;
        try {
            // selectedUdpFormInSideSheet format is { value: "formId|formVersion", label: "..." }
            const raw = (selectedUdpFormInSideSheet === null || selectedUdpFormInSideSheet === void 0 ? void 0 : selectedUdpFormInSideSheet.value) || '';
            const [id, versionStr] = raw.split('|');
            const version = Number(versionStr || 0);
            if (!id || !version) {
                console.warn('Invalid selection:', selectedUdpFormInSideSheet);
                setIsSidesheetOpen(false);
                return;
            }
            const fd = new FormData();
            fd.append('FormId', id);
            fd.append('FormVersion', String(version));
            fd.append('Status', String(UdpFormsSubmissionStatusEnum.Created));
            fd.append('Data', JSON.stringify({}));
            if (dueDateValue) {
                fd.append('DueDate', toUtcIsoAtLocalEndOfDay(dueDateValue));
            }
            if (generic1 !== undefined) {
                fd.append('Generic1', String(generic1));
            }
            if (generic2 !== undefined) {
                fd.append('Generic2', String(generic2));
            }
            if (generic3 !== undefined) {
                fd.append('Generic3', String(generic3));
            }
            const formSubmissionViewSearchResponse = await apiMutate(ConfigService.productV1ApiUrl, `UdpFormSubmission`, {
                method: 'POST',
                data: fd
            }, {});
            const newSubmissionId = (_a = formSubmissionViewSearchResponse === null || formSubmissionViewSearchResponse === void 0 ? void 0 : formSubmissionViewSearchResponse.data) === null || _a === void 0 ? void 0 : _a.id;
            setIsSidesheetOpen(false);
            const urlPath = generateFormRendererUrlPathUsingSubmissionId(newSubmissionId);
            history.push(urlPath);
        }
        catch (e) {
            console.error('handleSidesheetPrimaryClick error:', e);
            enqueueSnackbar(t('Error creating a new form.'), { variant: 'error', anchorOrigin: { vertical: 'top', horizontal: 'center' } });
        }
    };
    const handleSideSheetDueDateToggleChange = useCallback((checked) => {
        setContainsDueDate(checked);
        if (!checked)
            setDueDateValue(null); // hide + clear datapoint
    }, []);
    const handleDueDateChange = useCallback((e) => {
        var _a;
        const next = (_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.value;
        setDueDateValue(next);
    }, []);
    const handleSideSheetClosed = () => {
        setSelectedUdpFormInSideSheet({});
        setIsSidesheetOpen(false);
        setContainsDueDate(false);
        setDueDateValue(null);
    };
    const selectableItems = useMemo(() => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
        const map = new Map();
        for (const f of formDataRaw || []) {
            const formType = (_b = (_a = f.form_Type) !== null && _a !== void 0 ? _a : f.formType) !== null && _b !== void 0 ? _b : f.type;
            if (Number(formType) !== 1)
                continue;
            const formId = (_e = (_d = (_c = f.id) !== null && _c !== void 0 ? _c : f.form_Id) !== null && _d !== void 0 ? _d : f.formId) !== null && _e !== void 0 ? _e : String((_f = f === null || f === void 0 ? void 0 : f.Id) !== null && _f !== void 0 ? _f : '');
            const version = Number((_j = (_h = (_g = f.version) !== null && _g !== void 0 ? _g : f.form_Version) !== null && _h !== void 0 ? _h : f.formVersion) !== null && _j !== void 0 ? _j : 0);
            const name = (_p = (_o = (_m = (_l = (_k = f.name) !== null && _k !== void 0 ? _k : f.form_Name) !== null && _l !== void 0 ? _l : f.formName) !== null && _m !== void 0 ? _m : f.Form_Name) !== null && _o !== void 0 ? _o : f.displayName) !== null && _p !== void 0 ? _p : t('Untitled Form');
            const description = (_r = (_q = f.description) !== null && _q !== void 0 ? _q : f.form_Description) !== null && _r !== void 0 ? _r : '';
            const existing = map.get(formId);
            if (!existing || version > existing.version) {
                map.set(formId, { id: formId, name, version, description });
            }
        }
        return Array.from(map.values()).sort((a, b) => b.version - a.version);
    }, [formDataRaw, t]);
    const selectorOptions = useMemo(() => {
        return (selectableItems || []).map((s) => ({
            value: `${s.id}|${s.version}`,
            label: s.version ? `${s.name} (v${s.version})` : s.name
        }));
    }, [selectableItems]);
    const handleSelectedUdpFormInSideSheetChange = (event, newValue) => {
        if (newValue !== null) {
            setSelectedUdpFormInSideSheet(newValue);
        }
    };
    const getMainGridContent = ({ selectedNode, menuItemsList, idMap, classes }) => {
        if (!selectedNode) {
            return React.createElement(PageLoading, null);
        }
        const formId = parseIdAndVersion(selectedNode.id);
        const found = innerMenuItemList.find((form) => form.formId == formId);
        const formTitle = `${found === null || found === void 0 ? void 0 : found.name}` || 'Unknown Form';
        const newestFormVersion = formDataRaw
            .filter((formObj) => formObj.id == formId)
            .reduce((acc, curr) => {
            return Math.max(acc, curr.version);
        }, null);
        return (React.createElement(React.Fragment, null, React.createElement(SideSheet, { open: isSidesheetOpen, title: t('Submit New Form'), position: "right", width: '30%', buttonLabel: t('New'), 
            // Disable primary action when there is no selected form OR when
            // the user requested a due date but didn't pick one.
            buttonOneDisabled: !(selectedUdpFormInSideSheet === null || selectedUdpFormInSideSheet === void 0 ? void 0 : selectedUdpFormInSideSheet.value) || (containsDueDate && !dueDateValue), onSubmit: handleSidesheetPrimaryClick, onClose: handleSideSheetClosed }, React.createElement(FormControlLabel, { control: React.createElement(Switch, { size: "small", onChange: (e) => {
                    var _a;
                    return handleSideSheetDueDateToggleChange(Boolean((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.checked));
                } }), label: "Set a Due Date", style: { marginLeft: 0 } }), containsDueDate ? (React.createElement(TextField, { label: t('Due Date'), type: "date", variant: "outlined", size: "small", InputLabelProps: { shrink: true }, value: dueDateValue, onChange: handleDueDateChange, helperText: t('Set a due date at the end-of-day based on your local time.') })) : null, !((found === null || found === void 0 ? void 0 : found.id) && newestFormVersion) && (React.createElement(Autocomplete, { options: selectorOptions, getOptionLabel: (selectedOption) => selectedOption.label, onChange: handleSelectedUdpFormInSideSheetChange, 
            // Autocomplete expects the selected option object as value
            value: selectedUdpFormInSideSheet, disableClearable: true, size: "small", renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { label: t('Choose a Form'), variant: "outlined" }))) }))), React.createElement(SearchMethodUdpGrid, { searchMethodConfig: getSearchMethodConfig(formId), columnDefs: columnDefs, gridId: isManagerMode ? UdpFormsSubmissionGridIds.ManagerId : UdpFormsSubmissionGridIds.ResponderId, gridOptions: gridOptions, gridHeaderConfig: getGridHeaderConfig(formId, newestFormVersion, formTitle), gridFunctions: gridFunctions, gridApiCallback: handleGridApiCallback })));
    };
    useEffect(() => {
        var _a;
        if (!((_a = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) === null || _a === void 0 ? void 0 : _a.tenantId))
            return;
        const urlSearchObjs = parseSearchParamsIntoFilterObjects();
        setFormSubmissionUrlSearchObjs(urlSearchObjs); // THIS LINE TRIGGERS initialFilterModel
        let cancelled = false;
        (async () => {
            try {
                // replicate fetchSubmissions logic but using local urlSearchObjs (avoids depending on the state)
                let filterElements = [];
                filterElements.push({
                    searchField: 'Form_TenantId',
                    searchOperator: '=',
                    searchValue: tenant.activeTenant.tenantId
                });
                if (!isManagerMode) {
                    filterElements.push({
                        searchField: 'FormSubmission_UnityUserId',
                        searchOperator: '=',
                        searchValue: user.id
                    });
                }
                if (generic1 !== undefined) {
                    filterElements.push({
                        searchField: 'formSubmission_generic1',
                        searchOperator: '=',
                        searchValue: generic1
                    });
                }
                if (generic2 !== undefined) {
                    filterElements.push({
                        searchField: 'formSubmission_generic2',
                        searchOperator: '=',
                        searchValue: generic2
                    });
                }
                if (generic3 !== undefined) {
                    filterElements.push({
                        searchField: 'formSubmission_generic3',
                        searchOperator: '=',
                        searchValue: generic3
                    });
                }
                const formSubmissionViewSearchResponse = await apiMutate(ConfigService.productV1ApiUrl, `UdpFormWithSubmissionsView/search`, {
                    method: 'POST',
                    data: {
                        eagerLoad: false,
                        getAll: true,
                        filterElements
                    }
                }, {});
                if (cancelled)
                    return;
                const submissions = (formSubmissionViewSearchResponse === null || formSubmissionViewSearchResponse === void 0 ? void 0 : formSubmissionViewSearchResponse.data.pageList) || [];
                const processedSubmissions = submissions.filter((submission) => submission.form_TenantId === tenant.activeTenant.tenantId);
                setFormSubmissionViewDataRaw(processedSubmissions);
                await fetchForms();
            }
            catch (err) {
                console.error('fetching submissions/forms failed', err);
            }
        })();
        return () => {
            cancelled = true;
        };
    }, [
        location.search,
        (_a = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) === null || _a === void 0 ? void 0 : _a.tenantId,
        generic1,
        generic2,
        generic3,
        isManagerMode,
        user === null || user === void 0 ? void 0 : user.id,
        fetchForms
    ]);
    // derive menu items from fetched submissions (separate effect to avoid refetch loop)
    useEffect(() => {
        const innerMenuList = consolidateAndSortFormsByFormId(formDataRaw || [], formSubmissionViewDataRaw || []);
        innerMenuList.unshift({
            id: 'all-forms-key',
            name: allFormTitle !== null && allFormTitle !== void 0 ? allFormTitle : t(isManagerMode
                ? t('All Form Submissions')
                : t('All My Form Submissions')),
            submissionCount: (formSubmissionViewDataRaw === null || formSubmissionViewDataRaw === void 0 ? void 0 : formSubmissionViewDataRaw.length) || 0
        });
        setInnerMenuItemList(innerMenuList);
    }, [
        formSubmissionViewDataRaw,
        isManagerMode,
        consolidateAndSortFormsByFormId,
        formDataRaw,
        t,
        allFormTitle
    ]);
    return (React.createElement("div", null, React.createElement(CustomMenuPage, { menuTitle: menuTitle !== null && menuTitle !== void 0 ? menuTitle : t('Forms'), items: innerMenuItemList, idPrefix: "form-submission", showItemCount: true, itemCountAccessor: (item) => {
            var _a;
            return (_a = item === null || item === void 0 ? void 0 : item.submissionCount) !== null && _a !== void 0 ? _a : 0;
        }, mainContent: ({ selectedNode, menuItemsList, idMap, classes }) => {
            return (React.createElement("div", null, getMainGridContent({
                selectedNode,
                menuItemsList,
                idMap,
                classes
            })));
        } })));
};
//# sourceMappingURL=UdpFormsSubmissionGrid.js.map