using PowderCoating.Application.DTOs.Import;

namespace PowderCoating.Application.Interfaces;

/// <summary>
/// Service for bulk importing data via CSV files.
/// Supports customers, catalog items, and inventory items.
/// </summary>
public interface ICsvImportService
{
    /// <summary>
    /// Generate a CSV template file for customer imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateCustomerTemplate();

    /// <summary>
    /// Generate a CSV template file for catalog item imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateCatalogItemTemplate();

    /// <summary>
    /// Generate a CSV template file for inventory item imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateInventoryItemTemplate();

    /// <summary>
    /// Import customers from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportCustomersAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Import catalog items from a CSV stream.
    /// Creates categories on-the-fly if they don't exist.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <param name="revenueAccountId">Optional revenue account to assign to all imported items</param>
    /// <param name="cogsAccountId">Optional COGS account to assign to all imported items</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportCatalogItemsAsync(Stream csvStream, int companyId, int? revenueAccountId = null, int? cogsAccountId = null);

    /// <summary>
    /// Import inventory items from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <param name="inventoryAccountId">Optional inventory asset account to assign to all imported items</param>
    /// <param name="cogsAccountId">Optional COGS account to assign to all imported items</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportInventoryItemsAsync(Stream csvStream, int companyId, int? inventoryAccountId = null, int? cogsAccountId = null);

    /// <summary>
    /// Generate a CSV template file for quote imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateQuoteTemplate();

    /// <summary>
    /// Import quotes from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportQuotesAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for job imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateJobTemplate();

    /// <summary>
    /// Import jobs from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportJobsAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for appointment imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateAppointmentTemplate();

    /// <summary>
    /// Import appointments from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportAppointmentsAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for equipment imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateEquipmentTemplate();

    /// <summary>
    /// Import equipment from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportEquipmentAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for maintenance record imports.
    /// </summary>
    /// <returns>CSV file content as byte array</returns>
    byte[] GenerateMaintenanceTemplate();

    /// <summary>
    /// Import maintenance records from a CSV stream.
    /// </summary>
    /// <param name="csvStream">CSV file stream</param>
    /// <param name="companyId">Company ID for multi-tenancy</param>
    /// <returns>Import result with success/error counts</returns>
    Task<CsvImportResultDto> ImportMaintenanceAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for vendor imports.
    /// </summary>
    byte[] GenerateVendorTemplate();

    /// <summary>
    /// Import vendors from a CSV stream.
    /// Updates existing vendors matched by CompanyName; creates new ones otherwise.
    /// </summary>
    Task<CsvImportResultDto> ImportVendorsAsync(Stream csvStream, int companyId);

/// <summary>
    /// Generate a CSV template file for prep service imports.
    /// </summary>
    byte[] GeneratePrepServiceTemplate();

    /// <summary>
    /// Import prep services from a CSV stream.
    /// Updates existing services matched by ServiceName; creates new ones otherwise.
    /// </summary>
    Task<CsvImportResultDto> ImportPrepServicesAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for expense imports.
    /// </summary>
    byte[] GenerateExpenseTemplate();

    /// <summary>
    /// Import expenses from a CSV stream.
    /// ExpenseAccountNumber and PaymentAccountNumber are resolved by Account.AccountNumber.
    /// VendorName and JobNumber are optional lookups. ExpenseNumber is auto-generated when blank.
    /// </summary>
    Task<CsvImportResultDto> ImportExpensesAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for Chart of Accounts imports.
    /// </summary>
    byte[] GenerateChartOfAccountsTemplate();

    /// <summary>
    /// Import Chart of Accounts entries from a CSV stream.
    /// Existing accounts matched by AccountNumber are updated; new ones are created.
    /// System accounts (IsSystem=true) are never modified by import.
    /// </summary>
    Task<CsvImportResultDto> ImportChartOfAccountsAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Generate a CSV template file for invoice imports with headers matching the native export.
    /// </summary>
    byte[] GenerateInvoiceTemplate();

    /// <summary>
    /// Import invoice headers from a CSV stream. Customers are resolved by CustomerEmail then
    /// CustomerName. Duplicate detection uses InvoiceNumber as the unique key. Existing invoices
    /// are updated; new ones are created. Line items are imported separately via
    /// <see cref="ImportInvoiceItemsAsync"/>.
    /// </summary>
    Task<CsvImportResultDto> ImportInvoicesAsync(Stream csvStream, int companyId);

    /// <summary>
    /// Import invoice line items from a CSV stream. Each line is matched to its parent invoice by
    /// InvoiceNumber and its revenue account resolved (optional) from RevenueAccountNumber. Idempotent
    /// by description + total + display order. Run after invoices have been imported.
    /// </summary>
    Task<CsvImportResultDto> ImportInvoiceItemsAsync(Stream csvStream, int companyId);

    /// <summary>Import vendor bill headers. Vendor by name, AP account by number. Dedup by BillNumber.</summary>
    Task<CsvImportResultDto> ImportBillsAsync(Stream csvStream, int companyId);

    /// <summary>Import vendor bill line items. Matched to bills by BillNumber; account/job by number.</summary>
    Task<CsvImportResultDto> ImportBillLineItemsAsync(Stream csvStream, int companyId);

    /// <summary>Import customer deposits. Customer by name, bank account by number, applied invoice by number.</summary>
    Task<CsvImportResultDto> ImportDepositsAsync(Stream csvStream, int companyId);

    /// <summary>Import journal entry headers. Dedup by EntryNumber. Lines import separately.</summary>
    Task<CsvImportResultDto> ImportJournalEntriesAsync(Stream csvStream, int companyId);

    /// <summary>Import journal entry lines. Matched to entries by EntryNumber; account by number (required).</summary>
    Task<CsvImportResultDto> ImportJournalEntryLinesAsync(Stream csvStream, int companyId);

    /// <summary>Generate a CSV template file for invoice line-item imports.</summary>
    byte[] GenerateInvoiceItemTemplate();

    /// <summary>Generate a CSV template file for payment imports.</summary>
    byte[] GeneratePaymentTemplate();

    /// <summary>
    /// Import payment records from a CSV stream. Invoices are resolved by InvoiceNumber.
    /// Duplicates are detected by InvoiceNumber + PaymentDate + Amount and skipped.
    /// </summary>
    Task<CsvImportResultDto> ImportPaymentsAsync(Stream csvStream, int companyId);

    /// <summary>Generate a CSV template file for purchase order imports.</summary>
    byte[] GeneratePurchaseOrderTemplate();

    /// <summary>
    /// Import purchase order headers from a CSV stream. Vendors are resolved by company name.
    /// Existing POs matched by PoNumber are updated; new ones are created.
    /// </summary>
    Task<CsvImportResultDto> ImportPurchaseOrdersAsync(Stream csvStream, int companyId);
}
