// Tools Import/Export Wizard
(function () {
    'use strict';

    // ── Anti-forgery token ────────────────────────────────────────────────────
    const tokenInput = document.querySelector('input[name="__RequestVerificationToken"]');
    if (!tokenInput) { console.error('[Tools] Anti-forgery token not found'); return; }
    const token = tokenInput.value;

    // ── Account select data (embedded by Razor as JSON) ───────────────────────
    let accountData = { revenueAccounts: [], cogsAccounts: [], inventoryAccounts: [] };
    try {
        const el = document.getElementById('toolsAccountData');
        if (el) accountData = JSON.parse(el.textContent);
    } catch (e) { console.warn('[Tools] Could not parse account data'); }

    // ── Wizard state ──────────────────────────────────────────────────────────
    let wDir  = null;   // 'import' | 'export'
    let wFmt  = null;   // 'csv' | 'qb-desktop' | 'qb-online'
    let wItem = null;   // selected item object
    let wStep = 1;

    // ── Item catalog ──────────────────────────────────────────────────────────
    const ITEMS = [
        // ── CSV Import ──────────────────────────────────────────────────────
        { key: 'csv-customers',
          label: 'Customers', icon: 'bi-people', color: '#2563eb',
          desc: 'Contact info, addresses, and balances',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportCustomers', accept: '.csv',
          template: '/Tools/DownloadCustomerTemplate',
          tips: ['Download the CSV template to see the expected columns', 'One customer per row — existing records matched by company name are updated'] },

        { key: 'csv-vendors',
          label: 'Vendors', icon: 'bi-truck', color: '#d97706',
          desc: 'Supplier records and contact info',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportVendors', accept: '.csv',
          template: '/Tools/DownloadVendorTemplate',
          tips: ['Download the CSV template to see the expected columns', 'One vendor per row — existing records matched by company name are updated'] },

        { key: 'csv-catalog',
          label: 'Catalog Items', icon: 'bi-box-seam', color: '#059669',
          desc: 'Pre-priced service catalog entries',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportCatalogItems', accept: '.csv',
          template: '/Tools/DownloadCatalogTemplate',
          extraFields: [
              { name: 'revenueAccountId', label: 'Revenue Account', hint: 'Optional', accountKey: 'revenueAccounts' },
              { name: 'cogsAccountId',    label: 'COGS Account',    hint: 'Optional', accountKey: 'cogsAccounts' },
          ],
          tips: ['Download the CSV template', 'Optionally map to GL accounts before uploading'] },

        { key: 'csv-inventory',
          label: 'Inventory', icon: 'bi-boxes', color: '#0891b2',
          desc: 'Stock items, quantities, and unit costs',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportInventoryItems', accept: '.csv',
          template: '/Tools/DownloadInventoryTemplate',
          extraFields: [
              { name: 'inventoryAccountId', label: 'Inventory Asset Account', hint: 'Optional', accountKey: 'inventoryAccounts' },
              { name: 'cogsAccountId',      label: 'COGS Account',            hint: 'Optional', accountKey: 'cogsAccounts' },
          ],
          tips: ['Download the CSV template', 'Optionally map to GL accounts before uploading'] },

        { key: 'csv-quotes',
          label: 'Quotes', icon: 'bi-file-earmark-text', color: '#d97706',
          desc: 'Quote records with statuses and totals',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportQuotes', accept: '.csv',
          template: '/Tools/DownloadQuoteTemplate',
          tips: ['Download the CSV template', 'One quote per row'] },

        { key: 'csv-jobs',
          label: 'Jobs', icon: 'bi-briefcase', color: '#059669',
          desc: 'Job records with statuses and priorities',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportJobs', accept: '.csv',
          template: '/Tools/DownloadJobTemplate',
          tips: ['Download the CSV template', 'One job per row'] },

        { key: 'csv-invoices',
          label: 'Invoices', icon: 'bi-receipt', color: '#0891b2',
          desc: 'Invoice headers, amounts, and payment status',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportInvoices', accept: '.csv',
          template: '/Tools/DownloadInvoiceTemplate',
          tips: ['Download the CSV template to see the expected columns',
                 'Customers must exist before importing — matched by CustomerEmail then Customer name',
                 'Existing invoices matched by InvoiceNumber are updated; new ones are created',
                 'Line items import separately — run the Invoice Line Items import after this one'] },

        { key: 'csv-invoiceitems',
          label: 'Invoice Line Items', icon: 'bi-list-ul', color: '#0e7490',
          desc: 'Invoice line items with revenue account attribution',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportInvoiceItems', accept: '.csv',
          template: '/Tools/DownloadInvoiceItemTemplate',
          tips: ['Import invoices first — each line is matched to its parent by InvoiceNumber',
                 'RevenueAccountNumber is optional and matched against your Chart of Accounts',
                 'Re-running is safe — duplicate lines (same description + total + order) are skipped'] },

        { key: 'csv-appointments',
          label: 'Appointments', icon: 'bi-calendar-check', color: '#2563eb',
          desc: 'Scheduled customer appointments',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportAppointments', accept: '.csv',
          template: '/Tools/DownloadAppointmentTemplate',
          tips: ['Download the CSV template', 'One appointment per row'] },

        { key: 'csv-equipment',
          label: 'Equipment', icon: 'bi-tools', color: '#dc2626',
          desc: 'Equipment records and status',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportEquipment', accept: '.csv',
          template: '/Tools/DownloadEquipmentTemplate',
          tips: ['Download the CSV template', 'One equipment item per row'] },

        { key: 'csv-maintenance',
          label: 'Maintenance Records', icon: 'bi-wrench', color: '#6b7280',
          desc: 'Scheduled and completed maintenance',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportMaintenance', accept: '.csv',
          template: '/Tools/DownloadMaintenanceTemplate',
          tips: ['Download the CSV template', 'One maintenance record per row'] },


        { key: 'csv-prepservices',
          label: 'Prep Services', icon: 'bi-hammer', color: '#7c3aed',
          desc: 'Sandblasting, masking, and prep options',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportPrepServices', accept: '.csv',
          template: '/Tools/DownloadPrepServiceTemplate',
          tips: ['Existing services matched by name are updated'] },

        { key: 'csv-coa',
          label: 'Chart of Accounts', icon: 'bi-journal-text', color: '#374151',
          desc: 'GL accounts — import first (required for expenses and bills)',
          badge: 'Import first',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportChartOfAccounts', accept: '.csv',
          template: '/Tools/DownloadChartOfAccountsTemplate',
          tips: ['Download the CSV template to see required columns',
                 'Valid AccountType values: Asset, Liability, Equity, Revenue, CostOfGoods, Expense',
                 'Existing accounts matched by AccountNumber are updated; system accounts are never modified'] },

        { key: 'csv-expenses',
          label: 'Expenses', icon: 'bi-receipt-cutoff', color: '#dc2626',
          desc: 'Direct expenses with account, vendor, and job links',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportExpenses', accept: '.csv',
          template: '/Tools/DownloadExpenseTemplate',
          tips: ['Download the CSV template to see required columns',
                 'ExpenseAccountNumber and PaymentAccountNumber must match account numbers in your Chart of Accounts',
                 'VendorName and JobNumber are optional — leave blank if not applicable',
                 'Valid PaymentMethod values: Cash, Check, CreditDebitCard, BankTransferACH, DigitalPayment'] },

        { key: 'csv-payments',
          label: 'Payments', icon: 'bi-cash-coin', color: '#059669',
          desc: 'Invoice payment records with method and reference',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportPayments', accept: '.csv',
          template: '/Tools/DownloadPaymentTemplate',
          tips: ['Download the CSV template to see the expected columns',
                 'Invoices must exist before importing — matched by InvoiceNumber',
                 'Duplicate payments (same invoice + date + amount) are automatically skipped',
                 'Valid PaymentMethod values: Cash, Check, CreditDebitCard, BankTransferACH, DigitalPayment',
                 'Invoice AmountPaid and status are updated automatically after each payment'] },

        { key: 'csv-bills',
          label: 'Bills (AP)', icon: 'bi-file-earmark-ruled', color: '#b45309',
          desc: 'Vendor bill headers — vendor by name, AP account by number',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportBills', accept: '.csv',
          tips: ['Import Chart of Accounts and Vendors first',
                 'VendorName matches a vendor; APAccountNumber matches your Chart of Accounts',
                 'Existing bills matched by BillNumber are skipped',
                 'Import bill line items separately after this'] },

        { key: 'csv-billlineitems',
          label: 'Bill Line Items', icon: 'bi-list-ul', color: '#b45309',
          desc: 'Bill line items with expense account attribution',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportBillLineItems', accept: '.csv',
          tips: ['Import bills first — lines are matched to their parent by BillNumber',
                 'AccountNumber (expense/asset) and JobNumber are optional',
                 'Re-running is safe — duplicate lines are skipped'] },

        { key: 'csv-deposits',
          label: 'Customer Deposits', icon: 'bi-piggy-bank', color: '#059669',
          desc: 'Deposits with customer, bank account, and applied invoice',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportDeposits', accept: '.csv',
          tips: ['Import Customers and Chart of Accounts first',
                 'CustomerName matches a customer; DepositAccountNumber matches your Chart of Accounts',
                 'AppliedToInvoiceNumber is optional — links the deposit to an invoice',
                 'Existing deposits matched by ReceiptNumber are skipped'] },

        { key: 'csv-journalentries',
          label: 'Journal Entries', icon: 'bi-journal-bookmark', color: '#374151',
          desc: 'Journal entry headers — import lines separately after',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportJournalEntries', accept: '.csv',
          tips: ['Existing entries matched by EntryNumber are skipped',
                 'Valid Status values: Draft, Posted, Reversed',
                 'Import the entry lines separately after this'] },

        { key: 'csv-journalentrylines',
          label: 'Journal Entry Lines', icon: 'bi-list-columns', color: '#374151',
          desc: 'Debit/credit lines with account attribution',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportJournalEntryLines', accept: '.csv',
          tips: ['Import journal entries and Chart of Accounts first',
                 'Lines are matched to their entry by EntryNumber; AccountNumber is required',
                 'Each line is a debit or a credit — entries should balance'] },

        { key: 'csv-purchaseorders',
          label: 'Purchase Orders', icon: 'bi-cart', color: '#6b7280',
          desc: 'Purchase order headers with vendor, status, and totals',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportPurchaseOrders', accept: '.csv',
          template: '/Tools/DownloadPurchaseOrderTemplate',
          tips: ['Download the CSV template to see the expected columns',
                 'Vendors must exist before importing — matched by company name',
                 'Existing POs matched by PoNumber are updated; new ones are created',
                 'Valid Status values: Draft, Submitted, PartiallyReceived, Received, Cancelled',
                 'Line items are not part of the CSV — this imports PO headers and totals only'] },

        { key: 'csv-settings',
          label: 'Company Settings', icon: 'bi-gear', color: '#d97706',
          desc: 'Operating costs and configuration',
          dir: ['import'], fmt: ['csv'],
          endpoint: '/Tools/CsvImportCompanySettings', accept: '.csv',
          template: '/Tools/DownloadCompanySettingsTemplate',
          warning: 'This will overwrite your current company settings. Download a backup first.',
          tips: ['Download a backup of your current settings first', 'Modify the CSV, then upload it below'] },

        // ── CSV Export ──────────────────────────────────────────────────────
        { key: 'exp-customers',
          label: 'Customers', icon: 'bi-people', color: '#2563eb',
          desc: 'Contact info, addresses, and balances',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportCustomersCsv' },

        { key: 'exp-vendors',
          label: 'Vendors', icon: 'bi-truck', color: '#d97706',
          desc: 'Supplier records, contact info, and payment terms',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportVendorsCsv' },

        { key: 'exp-quotes',
          label: 'Quotes', icon: 'bi-file-earmark-text', color: '#0891b2',
          desc: 'Status, dates, totals, and customer info',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportQuotesCsv' },

        { key: 'exp-jobs',
          label: 'Jobs', icon: 'bi-briefcase', color: '#059669',
          desc: 'Status, priority, dates, and completion data',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportJobsCsv' },

        { key: 'exp-invoices',
          label: 'Invoices', icon: 'bi-receipt', color: '#0891b2',
          desc: 'Invoice headers, amounts, status, and customer info',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportInvoicesCsv' },

        { key: 'exp-invoiceitems',
          label: 'Invoice Line Items', icon: 'bi-list-ul', color: '#0e7490',
          desc: 'Line items with revenue account, keyed by invoice number',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportInvoiceItemsCsv' },

        { key: 'exp-payments',
          label: 'Payments', icon: 'bi-cash-coin', color: '#059669',
          desc: 'Invoice payment records with method and reference',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportPaymentsCsv' },

        { key: 'exp-bills',
          label: 'Bills (AP)', icon: 'bi-file-earmark-ruled', color: '#b45309',
          desc: 'Vendor bill headers with vendor and AP account',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportBillsCsv' },

        { key: 'exp-billlineitems',
          label: 'Bill Line Items', icon: 'bi-list-ul', color: '#b45309',
          desc: 'Bill line items with expense account, keyed by bill number',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportBillLineItemsCsv' },

        { key: 'exp-deposits',
          label: 'Customer Deposits', icon: 'bi-piggy-bank', color: '#059669',
          desc: 'Deposits with customer, bank account, and applied invoice',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportDepositsCsv' },

        { key: 'exp-journalentries',
          label: 'Journal Entries', icon: 'bi-journal-bookmark', color: '#374151',
          desc: 'Journal entry headers with reference and status',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportJournalEntriesCsv' },

        { key: 'exp-journalentrylines',
          label: 'Journal Entry Lines', icon: 'bi-list-columns', color: '#374151',
          desc: 'Debit/credit lines with account, keyed by entry number',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportJournalEntryLinesCsv' },

        { key: 'exp-appointments',
          label: 'Appointments', icon: 'bi-calendar-check', color: '#d97706',
          desc: 'Customer, type, status, and scheduling details',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportAppointmentsCsv' },

        { key: 'exp-catalog',
          label: 'Catalog Items', icon: 'bi-box-seam', color: '#6b7280',
          desc: 'SKU, pricing, categories, and descriptions',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportCatalogCsv' },

        { key: 'exp-inventory',
          label: 'Inventory', icon: 'bi-boxes', color: '#1f2937',
          desc: 'Quantities, costs, and location details',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportInventoryCsv' },

        { key: 'exp-equipment',
          label: 'Equipment', icon: 'bi-tools', color: '#dc2626',
          desc: 'Details, purchase info, and current status',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportEquipmentCsv' },

        { key: 'exp-maintenance',
          label: 'Maintenance Records', icon: 'bi-wrench', color: '#6b7280',
          desc: 'Scheduled and completed maintenance with equipment and costs',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportMaintenanceCsv' },


        { key: 'exp-prepservices',
          label: 'Prep Services', icon: 'bi-tools', color: '#7c3aed',
          desc: 'Preparation service catalog (sandblasting, stripping, etc.)',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportPrepServicesCsv' },

        { key: 'exp-purchaseorders',
          label: 'Purchase Orders', icon: 'bi-cart', color: '#6b7280',
          desc: 'Vendor, status, dates, and totals',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportPurchaseOrdersCsv' },

        { key: 'exp-coa',
          label: 'Chart of Accounts', icon: 'bi-journal-text', color: '#374151',
          desc: 'Full GL account list with types, balances, and account numbers',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportChartOfAccountsCsv' },

        { key: 'exp-expenses',
          label: 'Expenses', icon: 'bi-receipt-cutoff', color: '#dc2626',
          desc: 'Direct expenses with dates, accounts, vendors, and amounts',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportExpensesCsv' },

        { key: 'exp-settings',
          label: 'Company Settings', icon: 'bi-gear-fill', color: '#d97706',
          desc: 'Company info, operating costs, and preferences',
          dir: ['export'], fmt: ['csv'], exportUrl: '/Tools/ExportCompanySettingsCsv' },

        // ── QB Desktop Import ───────────────────────────────────────────────
        { key: 'qbd-coa',
          label: 'Chart of Accounts', icon: 'bi-journal-text', color: '#374151',
          desc: 'Account list — import this first (required for bills)',
          badge: 'Import first',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportChartOfAccounts', accept: '.iif,.txt',
          tips: ['Lists → Chart of Accounts → right-click → Export → save as .iif', 'Upload the .iif file below'] },

        { key: 'qbd-customers',
          label: 'Customers', icon: 'bi-people', color: '#2563eb',
          desc: 'Customer list from QB Desktop',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportCustomers', accept: '.iif,.txt',
          tips: ['File → Utilities → Export → Lists to IIF Files → select Customers', 'Upload the .iif file below'] },

        { key: 'qbd-vendors',
          label: 'Vendors', icon: 'bi-truck', color: '#d97706',
          desc: 'Vendor list from QB Desktop',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportVendors', accept: '.iif,.txt',
          tips: ['File → Utilities → Export → Lists to IIF Files → select Vendors', 'Upload the .iif file below'] },

        { key: 'qbd-catalog',
          label: 'Catalog Items', icon: 'bi-box-seam', color: '#059669',
          desc: 'Service items from QB Desktop',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportCatalogItems', accept: '.iif,.txt',
          tips: ['File → Utilities → Export → Lists to IIF Files → select Items', 'Upload the .iif file below'] },

        { key: 'qbd-inventory',
          label: 'Inventory Stock', icon: 'bi-boxes', color: '#0891b2',
          desc: 'Inventory Valuation Summary — include Pref Vendor column',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportQbInventoryValuation', accept: '.csv',
          tips: [
              'Reports → Inventory → Inventory Valuation Summary',
              'Customize Report → Display tab → check <strong>Pref Vendor</strong>',
              'Excel → Create New Worksheet → Comma Separated Values (.csv)',
              'Upload the saved .csv file below'
          ] },

        { key: 'qbd-invoices',
          label: 'Invoices', icon: 'bi-receipt', color: '#2563eb',
          desc: 'Customer Balance Detail report',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportQbInvoices', accept: '.csv',
          tips: ['Reports → Customers & Receivables → Customer Balance Detail', 'Set date range to <strong>All</strong>', 'Excel → Create New Worksheet → Comma Separated Values (.csv)', 'Upload the saved .csv file below'] },

        { key: 'qbd-transactions',
          label: 'Transactions', icon: 'bi-arrow-left-right', color: '#059669',
          desc: 'Transaction List by Customer report',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportQbTransactions', accept: '.csv',
          tips: ['Reports → Customers & Receivables → Transaction List by Customer', 'Set date range to <strong>All</strong>', 'Excel → Create New Worksheet → Comma Separated Values (.csv)', 'Upload the saved .csv file below'] },

        { key: 'qbd-bills',
          label: 'Bills & Payments', icon: 'bi-file-earmark-minus', color: '#dc2626',
          desc: 'Vendor Balance Detail report — imports bills and payments in one pass',
          dir: ['import'], fmt: ['qb-desktop'],
          endpoint: '/Tools/ImportQbBillsAndPayments', accept: '.csv',
          tips: [
              'Reports → Vendors &amp; Payables → Vendor Balance Detail',
              'Set date range to <strong>All</strong>',
              'Click <strong>Customize Report</strong> → <strong>Display</strong> tab → check <strong>Memo</strong> to include bill and payment descriptions',
              'Excel → Create New Worksheet → Comma Separated Values (.csv)',
              'Upload the file — bills are imported first, then payments are matched against them automatically'
          ] },

        // ── QB Online Import ────────────────────────────────────────────────
        { key: 'qbo-coa',
          label: 'Chart of Accounts', icon: 'bi-journal-text', color: '#374151',
          desc: 'Account List — import this first (required for invoices)',
          badge: 'Import first',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboChartOfAccounts', accept: '.xlsx,.xls',
          tips: [
              'Accounting (left nav) → Chart of Accounts → Download/Export button',
              '<strong>Or:</strong> Reports → search "Account List" → Export to Excel',
              'Upload the .xlsx file below'
          ] },

        { key: 'qbo-customers',
          label: 'Customers', icon: 'bi-people', color: '#2563eb',
          desc: 'Customer Contact List from QuickBooks Online',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboCustomers', accept: '.xlsx,.xls',
          tips: [
              'Reports → search "Customer Contact List" → Customize → add all desired columns → Export to Excel',
              '<strong>Tip:</strong> Add Billing Street, City, State, Zip columns via Customize → Rows/Columns for best results',
              'Upload the .xlsx file below'
          ] },

        { key: 'qbo-vendors',
          label: 'Vendors', icon: 'bi-truck', color: '#d97706',
          desc: 'Vendor Contact List from QuickBooks Online',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboVendors', accept: '.xlsx,.xls',
          tips: [
              'Reports → search "Vendor Contact List" → Customize → add all desired columns → Export to Excel',
              '<strong>Or:</strong> Expenses → Vendors → Export icon (box with arrow) → Export to Excel',
              'Upload the .xlsx file below'
          ] },

        { key: 'qbo-products',
          label: 'Products &amp; Services', icon: 'bi-box-seam', color: '#059669',
          desc: 'Product/service catalog from QuickBooks Online',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboCatalogItems', accept: '.xlsx,.xls',
          tips: [
              'Sales → Products and Services → Export to Excel icon (top right)',
              'Inventory-type items are imported as Inventory; all others as Catalog Items',
              'Items named <em>Category:Item Name</em> will have the category prefix stripped automatically',
              'Upload the .xlsx file below'
          ] },

        { key: 'qbo-invoices',
          label: 'Invoices', icon: 'bi-receipt', color: '#2563eb',
          desc: 'Invoice List report from QuickBooks Online',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboInvoices', accept: '.xlsx,.xls',
          tips: [
              'Reports → search "Invoice List" → set your date range → Export to Excel',
              'Customers must be imported first so invoices can be linked',
              'Invoice totals and open balances are imported; line item detail is not available in this report',
              'Upload the .xlsx file below'
          ] },

        { key: 'qbo-transactions',
          label: 'Transactions', icon: 'bi-arrow-left-right', color: '#059669',
          desc: 'Transaction List — applies payments to imported invoices',
          dir: ['import'], fmt: ['qb-online'],
          endpoint: '/Tools/ImportQboTransactions', accept: '.xlsx,.xls',
          tips: [
              'Reports → search "Transaction List by Date" → set All Dates → Export to Excel',
              'Only Payment/Receipt rows are processed; Invoice rows are skipped',
              'Invoices must be imported first so payments can be matched by reference number',
              'Upload the .xlsx file below'
          ] },

        // ── QB Export ───────────────────────────────────────────────────────
        { key: 'qb-exp-customers',
          label: 'Customers', icon: 'bi-people', color: '#2563eb',
          desc: 'Export all active customers',
          dir: ['export'], fmt: ['qb-desktop', 'qb-online'],
          exportUrlDesktop: '/Tools/ExportCustomers?format=desktop',
          exportUrlOnline:  '/Tools/ExportCustomers?format=online' },

        { key: 'qb-exp-vendors',
          label: 'Vendors', icon: 'bi-truck', color: '#d97706',
          desc: 'Export all active vendors to IIF format',
          dir: ['export'], fmt: ['qb-desktop'],
          exportUrl: '/Tools/ExportVendors' },

        { key: 'qb-exp-catalog',
          label: 'Catalog Items', icon: 'bi-box-seam', color: '#059669',
          desc: 'Export active catalog items as service items',
          dir: ['export'], fmt: ['qb-desktop', 'qb-online'],
          exportUrlDesktop: '/Tools/ExportCatalogItems?format=desktop',
          exportUrlOnline:  '/Tools/ExportCatalogItems?format=online' },
    ];

    // ── Helpers ───────────────────────────────────────────────────────────────
    function getExportUrl(item) {
        if (item.exportUrl) return item.exportUrl;
        if (wFmt === 'qb-online'  && item.exportUrlOnline)  return item.exportUrlOnline;
        if (item.exportUrlDesktop) return item.exportUrlDesktop;
        return '#';
    }

    function filteredItems() {
        return ITEMS.filter(it => it.dir.includes(wDir) && it.fmt.includes(wFmt));
    }

    // ── Wizard Navigation ─────────────────────────────────────────────────────
    window.wizardSetDirection = function (dir) {
        wDir = dir;
        wStep = 2;
        setBreadcrumb(2, dir === 'import' ? 'Import' : 'Export');
        document.getElementById('step2-heading').textContent =
            dir === 'import' ? 'Import from which format?' : 'Export to which format?';
        showStep(2);
        document.getElementById('wizardBackBtn').classList.remove('d-none');
    };

    window.wizardSetFormat = function (fmt) {
        wFmt = fmt;
        wStep = 3;
        const labels = { csv: 'CSV', 'qb-desktop': 'QB Desktop', 'qb-online': 'QB Online' };
        setBreadcrumb(3, labels[fmt] || fmt);
        renderStep3();
        showStep(3);
    };

    window.wizardBack = function () {
        if (wStep === 4) {
            wItem = null;
            wStep = 3;
            resetBreadcrumb(4, wDir === 'import' ? 'Import' : 'Export');
            renderStep3();
            showStep(3);
        } else if (wStep === 3) {
            wFmt = null;
            wStep = 2;
            resetBreadcrumb(3, 'Select');
            showStep(2);
        } else if (wStep === 2) {
            wDir = null;
            wStep = 1;
            resetBreadcrumb(2, 'Format');
            resetBreadcrumb(1, 'Direction');
            showStep(1);
            document.getElementById('wizardBackBtn').classList.add('d-none');
        }
    };

    window.wizardSelectItem = function (key) {
        wItem = ITEMS.find(it => it.key === key);
        if (!wItem) return;
        wStep = 4;
        setBreadcrumb(4, wItem.label);
        renderStep4();
        showStep(4);
    };

    function showStep(n) {
        [1, 2, 3, 4].forEach(function (s) {
            const el = document.getElementById('wizard-step-' + s);
            if (el) el.classList.toggle('d-none', s !== n);
        });
        updateBreadcrumbActive(n);
    }

    function setBreadcrumb(step, label) {
        const lbl = document.getElementById('bc-' + step + '-label');
        const bdg = document.getElementById('bc-' + step + '-badge');
        if (lbl) { lbl.textContent = label; lbl.className = 'small fw-semibold'; }
        if (bdg) bdg.className = 'badge rounded-pill bg-primary';
    }

    function resetBreadcrumb(step, label) {
        const lbl = document.getElementById('bc-' + step + '-label');
        const bdg = document.getElementById('bc-' + step + '-badge');
        if (lbl) { lbl.textContent = label; lbl.className = 'small text-muted'; }
        if (bdg) bdg.className = 'badge rounded-pill bg-secondary';
    }

    function updateBreadcrumbActive(currentStep) {
        for (let s = 1; s <= 4; s++) {
            const badge = document.getElementById('bc-' + s + '-badge');
            if (badge && s < currentStep && badge.className.includes('primary')) {
                badge.className = 'badge rounded-pill bg-success';
            }
        }
    }

    // ── Step 3: item selection grid ───────────────────────────────────────────
    function renderStep3() {
        const heading = document.getElementById('step3-heading');
        const grid    = document.getElementById('step3-grid');
        if (!heading || !grid) return;

        heading.textContent = wDir === 'import' ? 'What would you like to import?' : 'What would you like to export?';

        let html = '';

        // CSV Export: "Export All" shortcut
        if (wDir === 'export' && wFmt === 'csv') {
            html += `<div class="col-12 text-center mb-1">
                <a href="/Tools/ExportAllCsv" class="btn btn-primary px-4">
                    <i class="bi bi-file-earmark-zip me-1"></i>Export All as ZIP
                </a>
                <p class="text-muted small mt-2 mb-0">Or pick a specific data set below.</p>
            </div>`;
        }

        // QB Desktop Import: recommended order callout
        if (wDir === 'import' && wFmt === 'qb-desktop') {
            html += `<div class="col-12 mb-1">
                <div class="alert alert-info py-2 mb-0 small">
                    <i class="bi bi-list-ol me-1"></i>
                    <strong>Recommended order:</strong>
                    Chart of Accounts &rarr; Customers &rarr; Vendors &rarr; Catalog Items &rarr; Inventory &rarr; Invoices &rarr; Transactions &rarr; Bills &amp; Payments
                </div>
            </div>`;
        }

        filteredItems().forEach(function (item) {
            const badgeHtml = item.badge
                ? ` <span class="badge ms-1" style="background:#374151;font-size:0.68rem;vertical-align:middle">${item.badge}</span>`
                : '';
            html += `
            <div class="col-sm-6 col-lg-4">
                <div class="card h-100 border-2" role="button"
                     onclick="wizardSelectItem('${item.key}')"
                     style="cursor:pointer;border-color:${item.color}!important;transition:transform .1s"
                     onmouseover="this.style.transform='scale(1.02)'"
                     onmouseout="this.style.transform=''">
                    <div class="card-body py-3 px-3">
                        <div class="d-flex align-items-start gap-3">
                            <div style="width:42px;height:42px;border-radius:10px;background:${item.color}18;display:flex;align-items:center;justify-content:center;flex-shrink:0">
                                <i class="bi ${item.icon}" style="font-size:1.3rem;color:${item.color}"></i>
                            </div>
                            <div>
                                <div class="fw-semibold" style="font-size:0.93rem">${item.label}${badgeHtml}</div>
                                <div class="text-muted" style="font-size:0.8rem">${item.desc}</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>`;
        });

        if (!filteredItems().length) {
            html += `<div class="col-12 text-center text-muted py-5">
                <i class="bi bi-inbox" style="font-size:2.5rem"></i>
                <p class="mt-2 mb-0">No options available for this selection.</p>
            </div>`;
        }

        grid.innerHTML = html;
    }

    // ── Step 4: upload form or download button ────────────────────────────────
    async function renderStep4() {
        const container = document.getElementById('step4-content');
        if (!container || !wItem) return;

        const item     = wItem;
        const isImport = wDir === 'import';

        // Refresh account data from server if this card has account dropdowns,
        // so accounts imported earlier in the same page session are available.
        if (item.extraFields && item.extraFields.length) {
            try {
                const resp = await fetch('/Tools/GetImportAccounts');
                if (resp.ok) accountData = await resp.json();
            } catch (e) { /* keep whatever was loaded at page render */ }
        }

        // Tips list
        const tipsHtml = (item.tips || []).length
            ? `<ol class="small text-muted ps-3 mb-0">${item.tips.map(t => `<li>${t}</li>`).join('')}</ol>`
            : '';

        // Warning
        const warningHtml = item.warning
            ? `<div class="alert alert-warning py-2 mb-3 small"><i class="bi bi-exclamation-triangle-fill me-1"></i>${item.warning}</div>`
            : '';

        // Template download button
        const templateHtml = item.template
            ? `<div class="mb-4">
                <a href="${item.template}" class="btn btn-outline-secondary btn-sm">
                    <i class="bi bi-file-earmark-arrow-down me-1"></i>Download CSV Template
                </a>
               </div>`
            : '';

        // Extra account dropdowns
        let extraFieldsHtml = '';
        (item.extraFields || []).forEach(function (f) {
            const opts = (accountData[f.accountKey] || [])
                .map(o => `<option value="${o.value}">${o.text}</option>`)
                .join('');
            extraFieldsHtml += `
            <div class="mb-3">
                <label class="form-label small fw-semibold mb-1">${f.label}
                    <span class="text-muted fw-normal">${f.hint ? '— ' + f.hint : ''}</span>
                </label>
                <select name="${f.name}" class="form-select form-select-sm">
                    <option value="">(none)</option>
                    ${opts}
                </select>
            </div>`;
        });

        let actionHtml;

        if (isImport) {
            actionHtml = `
            ${warningHtml}
            ${templateHtml}
            <form id="step4-form" enctype="multipart/form-data">
                <div class="mb-3">
                    <label class="form-label small fw-semibold mb-1">
                        Select file <span class="text-muted fw-normal">${item.accept}</span>
                    </label>
                    <input type="file" class="form-control" id="step4-file" name="file" accept="${item.accept}" required />
                </div>
                ${extraFieldsHtml}
                <button type="submit" class="btn btn-primary" id="step4-btn">
                    <span class="spinner-border spinner-border-sm d-none me-1" id="step4-spinner" role="status"></span>
                    <i class="bi bi-upload me-1"></i>Import ${item.label}
                </button>
            </form>
            <div id="step4-results" class="mt-4 d-none">
                <hr>
                <div id="step4-summary" class="mb-2"></div>
                <div id="step4-errors"></div>
            </div>`;
        } else {
            const exportUrl = getExportUrl(item);
            const qbHelpHtml = (wFmt === 'qb-desktop' || wFmt === 'qb-online')
                ? `<div class="alert alert-info small mt-3 mb-0">
                    <i class="bi bi-info-circle me-1"></i>
                    <strong>Importing into QuickBooks${wFmt === 'qb-online' ? ' Online' : ' Desktop'}:</strong>
                    ${wFmt === 'qb-desktop'
                        ? 'File → Utilities → Import → IIF Files → select the downloaded file.'
                        : 'Settings → Import Data → select the data type, then upload the file.'}
                   </div>`
                : '';
            actionHtml = `
            <a href="${exportUrl}" class="btn btn-success btn-lg">
                <i class="bi bi-download me-2"></i>Download ${item.label}
            </a>
            ${qbHelpHtml}`;
        }

        container.innerHTML = `
        <div class="row g-4">
            <div class="col-md-4">
                <div class="d-flex align-items-center gap-2 mb-3">
                    <div style="width:40px;height:40px;border-radius:8px;background:${item.color}18;display:flex;align-items:center;justify-content:center;flex-shrink:0">
                        <i class="bi ${item.icon}" style="color:${item.color};font-size:1.2rem"></i>
                    </div>
                    <div>
                        <div class="fw-bold">${item.label}</div>
                        <div class="text-muted small">${item.desc}</div>
                    </div>
                </div>
                ${tipsHtml}
            </div>
            <div class="col-md-8">
                ${actionHtml}
            </div>
        </div>`;

        if (isImport) {
            document.getElementById('step4-form').addEventListener('submit', runImport);
        }
    }

    // ── Import runner ─────────────────────────────────────────────────────────
    async function runImport(e) {
        e.preventDefault();
        const item      = wItem;
        const fileInput = document.getElementById('step4-file');
        const btn       = document.getElementById('step4-btn');
        const spinner   = document.getElementById('step4-spinner');
        const resultsDiv = document.getElementById('step4-results');
        const summaryDiv = document.getElementById('step4-summary');
        const errorsDiv  = document.getElementById('step4-errors');

        if (!fileInput || !fileInput.files.length) {
            if (typeof showWarning === 'function') showWarning('Please select a file first');
            return;
        }

        btn.disabled = true;
        if (spinner) spinner.classList.remove('d-none');
        resultsDiv.classList.add('d-none');

        const formData = new FormData(document.getElementById('step4-form'));
        formData.append('__RequestVerificationToken', token);

        try {
            const response = await fetch(item.endpoint, { method: 'POST', body: formData });
            if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            const ct = response.headers.get('content-type') || '';
            if (!ct.includes('application/json')) throw new Error('Unexpected response from server — check the browser console');
            const result = await response.json();
            displaySuccess(summaryDiv, errorsDiv, resultsDiv, result);
            if (result.success) {
                if (typeof showSuccess === 'function') showSuccess(result.message || 'Import completed');
            } else {
                if (typeof showError === 'function') showError(result.message || 'Import completed with errors');
            }
        } catch (err) {
            console.error('[Tools] Import error:', err);
            displayError(summaryDiv, errorsDiv, resultsDiv, err.message, err.stack);
            if (typeof showError === 'function') showError(err.message);
        } finally {
            btn.disabled = false;
            if (spinner) spinner.classList.add('d-none');
        }
    }

    // ── Result display ────────────────────────────────────────────────────────
    function displayError(summaryDiv, errorsDiv, resultsDiv, msg, detail) {
        if (summaryDiv) {
            summaryDiv.innerHTML = `<div class="alert alert-danger mb-0">
                <i class="bi bi-exclamation-triangle me-1"></i>
                <strong>Import Failed:</strong> ${msg}
            </div>`;
        }
        if (errorsDiv) {
            errorsDiv.innerHTML = detail
                ? `<details class="mt-2" open>
                    <summary class="text-danger"><strong>Error Details</strong></summary>
                    <pre class="mt-2 small bg-light p-2 rounded" style="max-height:300px;overflow-y:auto">${detail}</pre>
                   </details>`
                : '';
        }
        if (resultsDiv) resultsDiv.classList.remove('d-none');
    }

    function displaySuccess(summaryDiv, errorsDiv, resultsDiv, result) {
        // Normalise both QB-format (importedCount/totalRecords) and
        // CSV bulk-import format (successCount/totalRows) so this function
        // works regardless of which endpoint was called.
        const totalRecords  = result.totalRecords  ?? result.totalRows    ?? 0;
        const importedCount = result.importedCount ?? result.successCount ?? 0;
        const updatedCount  = result.updatedCount  ?? 0;
        const skippedCount  = result.skippedCount  ?? 0;

        // QB format puts everything in result.errors with a severity field.
        // CSV format puts error strings in result.errors and warning strings
        // in a separate result.warnings array. Normalise both into one list.
        const allMessages = [
            ...(result.errors || []).map(function (e) {
                return typeof e === 'string' ? { severity: 'Error', displayMessage: e } : e;
            }),
            ...(result.warnings || []).map(function (w) {
                return typeof w === 'string' ? { severity: 'Warning', displayMessage: w } : w;
            }),
        ];

        const errors   = allMessages.filter(function (e) { return (e.severity || 'Error') === 'Error'; });
        const warnings = allMessages.filter(function (e) { return e.severity === 'Warning'; });
        const skipped  = allMessages.filter(function (e) { return e.severity === 'Skipped'; });

        if (summaryDiv) {
            const icon = errors.length > 0
                ? '<i class="bi bi-exclamation-triangle text-warning me-1"></i>'
                : '<i class="bi bi-check-circle text-success me-1"></i>';
            summaryDiv.innerHTML = `
            <div class="d-flex justify-content-between align-items-start flex-wrap gap-2">
                <div>
                    ${icon}<strong>Results</strong> &nbsp;
                    Total: <strong>${totalRecords}</strong> &nbsp;&nbsp;
                    Imported: <span class="text-success fw-bold">${importedCount}</span> &nbsp;&nbsp;
                    ${updatedCount > 0 ? `Updated: <span class="text-info fw-bold">${updatedCount}</span> &nbsp;&nbsp;` : ''}
                    Skipped: <span class="text-warning fw-bold">${skippedCount}</span>
                    ${errors.length > 0 ? ` &nbsp;&nbsp; Errors: <span class="text-danger fw-bold">${errors.length}</span>` : ''}
                </div>
                <button class="btn btn-outline-secondary btn-sm flex-shrink-0"
                        onclick="downloadImportReport(this)"
                        data-result='${JSON.stringify(result).replace(/'/g, '&#39;')}'>
                    <i class="bi bi-download me-1"></i>Download Report
                </button>
            </div>`;
        }

        if (errorsDiv) {
            let html = '';
            if (errors.length) {
                html += `<details class="mt-2" open>
                    <summary class="text-danger"><strong>${errors.length} Error(s)</strong></summary>
                    <ul class="mt-1 small mb-0">${errors.map(function (e) {
                        return '<li>' + (e.displayMessage || e.errorMessage || JSON.stringify(e)) + '</li>';
                    }).join('')}</ul>
                </details>`;
            }
            if (warnings.length) {
                html += `<details class="mt-2">
                    <summary class="text-warning"><strong>${warnings.length} Warning(s)</strong></summary>
                    <ul class="mt-1 small mb-0">${warnings.map(function (e) {
                        return '<li>' + (e.displayMessage || e.errorMessage) + '</li>';
                    }).join('')}</ul>
                </details>`;
            }
            if (skipped.length) {
                html += `<details class="mt-2">
                    <summary class="text-secondary"><strong>${skipped.length} Skipped</strong></summary>
                    <ul class="mt-1 small mb-0">${skipped.map(function (e) {
                        return '<li>' + (e.recordName || '') + (e.errorMessage ? ' — ' + e.errorMessage : '') + '</li>';
                    }).join('')}</ul>
                </details>`;
            }
            errorsDiv.innerHTML = html;
        }

        if (resultsDiv) resultsDiv.classList.remove('d-none');
    }

    // ── Download report (called from inline onclick) ──────────────────────────
    window.downloadImportReport = function (btn) {
        try {
            const result = JSON.parse(btn.getAttribute('data-result'));
            const importedCount = result.importedCount ?? result.successCount ?? 0;
            const updatedCount  = result.updatedCount  ?? 0;
            const skippedCount  = result.skippedCount  ?? 0;
            const rows = [['Status', 'Record', 'Field', 'Message']];
            rows.push(['Imported', importedCount, '', '']);
            if (updatedCount > 0) rows.push(['Updated', updatedCount, '', '']);
            rows.push(['Skipped',  skippedCount,  '', '']);
            // Normalise errors: QB format = objects, CSV format = plain strings
            const allErrors = [
                ...(result.errors || []).map(function (e) {
                    return typeof e === 'string' ? { severity: 'Error', recordName: '', fieldName: '', errorMessage: e } : e;
                }),
                ...(result.warnings || []).map(function (w) {
                    return typeof w === 'string' ? { severity: 'Warning', recordName: '', fieldName: '', errorMessage: w } : w;
                }),
            ];
            allErrors.forEach(function (e) {
                rows.push([e.severity || 'Error', e.recordName || '', e.fieldName || '', e.errorMessage || '']);
            });
            const csv = rows.map(function (r) {
                return r.map(function (c) { return '"' + String(c).replace(/"/g, '""') + '"'; }).join(',');
            }).join('\r\n');
            const a = document.createElement('a');
            a.href     = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));
            a.download = 'import-report-' + new Date().toISOString().slice(0, 10) + '.csv';
            a.click();
            URL.revokeObjectURL(a.href);
        } catch (err) {
            console.error('[Tools] Report error:', err);
        }
    };

})();
