import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { RECORDS_PER_PAGE } from 'src/constants/urls';
import { LmsTableSettingsEntity } from 'src/entities/LmsTableSettings.entity';
import { TableSettingsDto } from 'src/modules/backend/user-settings/dto/table-settings-dto';
import { Repository } from 'typeorm';

/**
 * TableSettingsService - Service for managing user table/view settings
 *
 * This service handles user preferences for data table displays, including:
 * - Column visibility toggles (which columns to show/hide)
 * - Records per page configuration
 * - User-specific table settings persistence
 *
 * Typical use cases:
 * - Customizable data tables in admin panels
 * - User-preferred column layouts
 * - Saved pagination preferences
 *
 * @example
 * // Get user's table settings for student list
 * const settings = await tableSettingsService.autoGetPageSettings({
 *   user_id: 123,
 *   setting_type: 'students_table',
 *   columns: { id: 'ID', name: 'Name', email: 'Email' }
 * });
 *
 * @example
 * // Result format
 * {
 *   columns: [
 *     { key: 'id', title: 'ID', is_checked: true },
 *     { key: 'name', title: 'Name', is_checked: true },
 *     { key: 'email', title: 'Email', is_checked: false }
 *   ],
 *   record_per_page: 25
 * }
 */
@Injectable()
export class TableSettingsService {
  constructor(
    @InjectRepository(LmsTableSettingsEntity)
    private readonly settingsRepository: Repository<LmsTableSettingsEntity>,
  ) {}

  /**
   * Converts column definitions to default column settings
   *
   * Transforms a simple key-title mapping into structured column
   * settings with all columns enabled by default.
   *
   * @param columns - Object mapping column keys to display titles
   * @returns Array of column setting objects with default visibility
   *
   * @example
   * Input: { id: 'ID', name: 'Name' }
   * Output: [
   *   { key: 'id', title: 'ID', is_checked: true },
   *   { key: 'name', title: 'Name', is_checked: true }
   * ]
   */
  private autoSetDefaultColumns(columns: any[]): any[] {
    // Convert object entries to column settings array
    return Object.entries(columns).map(([key, title]) => ({
      key, // Column identifier (database field name)
      title, // Display title for the column
      is_checked: true, // Default: column is visible
      // Additional properties could be added:
      // width: '100px',
      // sortable: true,
      // filterable: false,
    }));
  }

  /**
   * Retrieves table display settings for a user and table type
   *
   * Combines user-specific saved settings with default values:
   * 1. Looks up saved settings for the user and table type
   * 2. Uses saved column preferences or creates defaults
   * 3. Uses saved records-per-page or system default
   *
   * @param params - Parameters for retrieving settings
   * @param params.user_id - User identifier
   * @param params.setting_type - Table type identifier (e.g., 'students_table', 'courses_table')
   * @param params.columns - Default column definitions for this table type
   * @returns Object containing column settings and records per page
   *
   * @note If user has no saved settings, defaults are created and returned
   * @note Records per page falls back to RECORDS_PER_PAGE constant
   * @note Affiliate user ID support is commented out but available
   */
  async autoGetPageSettings(params: TableSettingsDto): Promise<any> {
    // Build query conditions for finding user settings
    const whereConditions: any = {
      user_id: params.user_id,
      setting_type: params.setting_type,
      // Uncomment if affiliate support is needed:
      // affiliate_user_id: params.affiliate_user_id,
    };

    // Query database for user's saved settings
    const userSettings = await this.settingsRepository.findOne({
      where: whereConditions,
    });

    // Determine column settings: use saved or create defaults
    const customColumns =
      !userSettings?.setting_pack || userSettings.setting_pack === null
        ? this.autoSetDefaultColumns(params.columns) // Create defaults
        : userSettings.setting_pack; // Use saved settings

    // Determine records per page: use saved or system default
    const recordPerPage =
      userSettings?.record_per_page && userSettings.record_per_page > 0
        ? userSettings.record_per_page // Use saved preference
        : RECORDS_PER_PAGE; // Use system default

    return {
      columns: customColumns,
      record_per_page: recordPerPage,
      // Additional metadata could be added:
      // setting_id: userSettings?.id,
      // has_saved_settings: !!userSettings,
    };
  }

  /**
   * Enhanced methods that could be added:
   *
   * async savePageSettings(params: SaveTableSettingsDto): Promise<void> {
   *   // Save or update user's table settings
   * }
   *
   * async resetToDefaults(userId: number, settingType: string): Promise<void> {
   *   // Reset user's settings to defaults
   * }
   *
   * async getAvailableColumns(settingType: string): Promise<ColumnDefinition[]> {
   *   // Get all available columns for a table type
   * }
   *
   * async migrateUserSettings(oldUserId: number, newUserId: number): Promise<void> {
   *   // Transfer settings between users
   * }
   */
}
