// Setup Detection - First-time user setup and installer detection
class SetupDetector {
  constructor() {
    this.setupSteps = new Map();
    this.currentStep = 0;
    this.isFirstTime = false;
    this.setupComplete = false;
  }

  // Initialize setup detection
  async initialize() {
    this.setupSteps = this.defineSetupSteps();
    this.isFirstTime = await this.detectFirstTime();
    this.setupComplete = !this.isFirstTime;
    
    return {
      isFirstTime: this.isFirstTime,
      setupComplete: this.setupComplete
    };
  }

  // Define setup steps
  defineSetupSteps() {
    return new Map([
      ['welcome', {
        title: 'Welcome to LibrePortal',
        description: 'Let\'s get your Docker management system set up',
        component: 'welcome-step'
      }],
      ['requirements', {
        title: 'System Requirements',
        description: 'Checking your system compatibility',
        component: 'requirements-step',
        check: () => this.checkSystemRequirements()
      }],
      ['directories', {
        title: 'Directory Setup',
        description: 'Creating necessary directories',
        component: 'directories-step',
        check: () => this.checkDirectories()
      }],
      ['permissions', {
        title: 'Permissions Check',
        description: 'Verifying file permissions',
        component: 'permissions-step',
        check: () => this.checkPermissions()
      }],
      ['configuration', {
        title: 'Basic Configuration',
        description: 'Setting up initial configuration',
        component: 'config-step',
        check: () => this.checkBasicConfig()
      }],
      ['complete', {
        title: 'Setup Complete',
        description: 'Your LibrePortal system is ready',
        component: 'complete-step'
      }]
    ]);
  }

  // Detect if this is first-time setup. Source of truth is the server-side
  // lock file at <containers-root>/libreportal/frontend/data/.setup_complete
  // — that's what the bash setupApply function creates after a successful
  // wizard run. localStorage is no longer used because per-browser state
  // gives wrong answers (different browsers would each see "first install").
  async detectFirstTime() {
    try {
      const res = await fetch('/api/setup/status');
      if (!res.ok) return true;
      const data = await res.json();
      return !data.complete;

    } catch (error) {
      console.error('Error detecting first-time setup:', error);
      return true; // Assume first time on error
    }
  }

  // Check system requirements
  async checkSystemRequirements() {
    const checks = [];

    // Check browser compatibility
    const browserCheck = this.checkBrowserCompatibility();
    checks.push({
      name: 'Browser Compatibility',
      status: browserCheck.passed,
      details: browserCheck.details
    });

    // Check JavaScript features
    const jsCheck = this.checkJavaScriptFeatures();
    checks.push({
      name: 'JavaScript Features',
      status: jsCheck.passed,
      details: jsCheck.details
    });

    // Check storage availability
    const storageCheck = this.checkStorageAvailability();
    checks.push({
      name: 'Local Storage',
      status: storageCheck.passed,
      details: storageCheck.details
    });

    // Check network connectivity
    const networkCheck = await this.checkNetworkConnectivity();
    checks.push({
      name: 'Network Connectivity',
      status: networkCheck.passed,
      details: networkCheck.details
    });

    return {
      passed: checks.every(check => check.status),
      checks
    };
  }

  // Check browser compatibility
  checkBrowserCompatibility() {
    const userAgent = navigator.userAgent;
    const isChrome = /Chrome/.test(userAgent) && /Google Inc/.test(navigator.vendor);
    const isFirefox = /Firefox/.test(userAgent);
    const isSafari = /Safari/.test(userAgent) && /Apple Computer/.test(navigator.vendor);
    const isEdge = /Edg/.test(userAgent);

    const supported = isChrome || isFirefox || isSafari || isEdge;
    
    return {
      passed: supported,
      details: {
        browser: this.getBrowserName(),
        supported,
        version: navigator.userAgent.match(/(?:Chrome|Firefox|Safari|Edge)\/(\d+)/)?.[1] || 'Unknown'
      }
    };
  }

  // Get browser name
  getBrowserName() {
    const userAgent = navigator.userAgent;
    if (/Chrome/.test(userAgent) && /Google Inc/.test(navigator.vendor)) return 'Chrome';
    if (/Firefox/.test(userAgent)) return 'Firefox';
    if (/Safari/.test(userAgent) && /Apple Computer/.test(navigator.vendor)) return 'Safari';
    if (/Edg/.test(userAgent)) return 'Edge';
    return 'Unknown';
  }

  // Check JavaScript features
  checkJavaScriptFeatures() {
    const features = [
      { name: 'Fetch API', check: () => typeof fetch !== 'undefined' },
      { name: 'Promises', check: () => typeof Promise !== 'undefined' },
      { name: 'Arrow Functions', check: () => { try { eval('() => {}'); return true; } catch { return false; } } },
      { name: 'Async/Await', check: () => { try { eval('async () => {}'); return true; } catch { return false; } } },
      { name: 'Map/Set', check: () => typeof Map !== 'undefined' && typeof Set !== 'undefined' },
      { name: 'LocalStorage', check: () => typeof Storage !== 'undefined' }
    ];

    const results = features.map(feature => ({
      name: feature.name,
      supported: feature.check()
    }));

    const allSupported = results.every(result => result.supported);

    return {
      passed: allSupported,
      details: {
        features: results,
        totalSupported: results.filter(r => r.supported).length,
        totalFeatures: results.length
      }
    };
  }

  // Check storage availability
  checkStorageAvailability() {
    try {
      const testKey = 'libreportal_test';
      localStorage.setItem(testKey, 'test');
      localStorage.removeItem(testKey);
      
      return {
        passed: true,
        details: {
          available: true,
          quota: 'Available'
        }
      };
    } catch (error) {
      return {
        passed: false,
        details: {
          available: false,
          error: error.message
        }
      };
    }
  }

  // Check network connectivity
  async checkNetworkConnectivity() {
    try {
      const response = await fetch('/', { method: 'HEAD', cache: 'no-cache' });
      
      return {
        passed: response.ok,
        details: {
          status: response.status,
          statusText: response.statusText,
          online: navigator.onLine
        }
      };
    } catch (error) {
      return {
        passed: false,
        details: {
          error: error.message,
          online: navigator.onLine
        }
      };
    }
  }

  // Check required directories
  async checkDirectories() {
    const requiredPaths = [
      '/data/apps/',
      '/data/config/',
      '/data/backup/',
      '/containers/libreportal/'
    ];

    const checks = [];
    
    for (const path of requiredPaths) {
      try {
        // Try to access a file in the directory to check if it exists
        const testFile = path.endsWith('/') ? path + '.gitkeep' : path;
        const response = await fetch(testFile, { method: 'HEAD' });
        
        checks.push({
          path,
          exists: response.ok || response.status === 404 // 404 means directory exists but file doesn't
        });
      } catch (error) {
        checks.push({
          path,
          exists: false,
          error: error.message
        });
      }
    }

    const allExist = checks.every(check => check.exists);

    return {
      passed: allExist,
      details: {
        directories: checks,
        totalExists: checks.filter(c => c.exists).length,
        totalDirectories: checks.length
      }
    };
  }

  // Check file permissions
  async checkPermissions() {
    const testFiles = [
      '/data/apps/generated/apps.json',
      '/data/apps/apps-categories.json',
      '/data/config/generated/configs.json'
    ];

    const checks = [];
    
    for (const file of testFiles) {
      try {
        const response = await fetch(file, { method: 'HEAD' });
        
        checks.push({
          file,
          readable: response.ok,
          status: response.status
        });
      } catch (error) {
        checks.push({
          file,
          readable: false,
          error: error.message
        });
      }
    }

    const allReadable = checks.every(check => check.readable);

    return {
      passed: allReadable,
      details: {
        files: checks,
        totalReadable: checks.filter(c => c.readable).length,
        totalFiles: checks.length
      }
    };
  }

  // Check basic configuration
  async checkBasicConfig() {
    try {
      // Check for basic config files
      const configFiles = [
        '/data/config/generated/configs.json'
      ];

      for (const file of configFiles) {
        const response = await fetch(file, { method: 'HEAD' });
        if (!response.ok) {
          return {
            passed: false,
            details: {
              missing: file,
              error: 'Configuration file not found'
            }
          };
        }
      }

      // Try to load and validate config structure
      const configResponse = await fetch('/data/config/generated/configs.json');
      if (configResponse.ok) {
        const config = await configResponse.json();
        
        return {
          passed: true,
          details: {
            configLoaded: true,
            configType: typeof config,
            hasData: Object.keys(config).length > 0
          }
        };
      }

      return {
        passed: false,
        details: {
          error: 'Failed to load configuration'
        }
      };

    } catch (error) {
      return {
        passed: false,
        details: {
          error: error.message
        }
      };
    }
  }

  // Get setup step by ID
  getStep(stepId) {
    return this.setupSteps.get(stepId);
  }

  // Get all setup steps
  getAllSteps() {
    return Array.from(this.setupSteps.entries()).map(([id, step]) => ({
      id,
      ...step
    }));
  }

  // Get next step
  getNextStep() {
    const steps = Array.from(this.setupSteps.keys());
    const nextIndex = this.currentStep + 1;
    
    if (nextIndex < steps.length) {
      return steps[nextIndex];
    }
    
    return null;
  }

  // Get previous step
  getPreviousStep() {
    const steps = Array.from(this.setupSteps.keys());
    const prevIndex = this.currentStep - 1;
    
    if (prevIndex >= 0) {
      return steps[prevIndex];
    }
    
    return null;
  }

  // Move to specific step
  goToStep(stepId) {
    if (this.setupSteps.has(stepId)) {
      this.currentStep = Array.from(this.setupSteps.keys()).indexOf(stepId);
      return true;
    }
    return false;
  }

  // Mark setup as complete
  markSetupComplete() {
    this.setupComplete = true;
    this.isFirstTime = false;
    localStorage.setItem('libreportal_setup_complete', 'true');
    localStorage.setItem('libreportal_setup_date', new Date().toISOString());
  }

  // Reset setup (for testing/re-setup)
  resetSetup() {
    this.setupComplete = false;
    this.isFirstTime = true;
    this.currentStep = 0;
    localStorage.removeItem('libreportal_setup_complete');
    localStorage.removeItem('libreportal_setup_date');
  }

  // Get setup status
  getSetupStatus() {
    return {
      isFirstTime: this.isFirstTime,
      setupComplete: this.setupComplete,
      currentStep: this.currentStep,
      totalSteps: this.setupSteps.size,
      setupDate: localStorage.getItem('libreportal_setup_date')
    };
  }
}

// Global instance
window.SetupDetector = SetupDetector;
