import { Injectable, inject, effect } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { SettingsService } from './settings.service';
import { ConnectivityService } from './connectivity.service';
import { ComunitaService } from './comunita.service';
import { VERSION } from '../version';

@Injectable({
  providedIn: 'root'
})
export class StatsService {
  private http = inject(HttpClient);
  private settingsService = inject(SettingsService);
  private connectivityService = inject(ConnectivityService);
  private comunitaService = inject(ComunitaService);

  constructor() {
    // Automatically trigger sync when the device becomes online
    effect(() => {
      if (this.connectivityService.isOnline()) {
        this.syncStats();
      }
    });
  }

  private getOrCreateUUID(): string {
    let uuid = localStorage.getItem('stats-uuid');
    if (!uuid) {
      uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
      localStorage.setItem('stats-uuid', uuid);
    }
    return uuid;
  }

  private formatDateTime(date: Date): string {
    const pad = (n: number) => n.toString().padStart(2, '0');
    const y = date.getFullYear();
    const m = pad(date.getMonth() + 1);
    const d = pad(date.getDate());
    const h = date.getHours();
    const min = pad(date.getMinutes());
    const s = pad(date.getSeconds());
    return `${y}-${m}-${d} ${h}:${min}:${s}`;
  }

  private getBrowserModel(): string {
    const ua = navigator.userAgent;
    if (ua.includes('Chrome')) return 'Chrome';
    if (ua.includes('Safari') && !ua.includes('Chrome')) return 'Safari';
    if (ua.includes('Firefox')) return 'Firefox';
    return 'Browser';
  }

  private getLocalLogs(): any[] {
    const data = localStorage.getItem('stats-logs-queue');
    return data ? JSON.parse(data) : [];
  }

  private saveLocalLogs(logs: any[]) {
    localStorage.setItem('stats-logs-queue', JSON.stringify(logs));
  }

  private clearLocalLogs() {
    localStorage.removeItem('stats-logs-queue');
  }

  private getLocalSongSettings(): any[] {
    const data = localStorage.getItem('stats-settings-queue');
    return data ? JSON.parse(data) : [];
  }

  private saveLocalSongSettings(settings: any[]) {
    localStorage.setItem('stats-settings-queue', JSON.stringify(settings));
  }

  logSongView(idCanti: number, timeSpentSeconds: number) {
    if (!this.settingsService.invioDatiStatistici()) return;
    if (timeSpentSeconds < 1) return; // Ignore very short views

    console.log('📊 StatsService: logSongView called for song', idCanti, 'timespent:', timeSpentSeconds);

    const logEntry = {
      uuid: this.getOrCreateUUID(),
      id_canti: idCanti.toString(),
      data_log: this.formatDateTime(new Date()),
      version: VERSION,
      tempo: Math.round(timeSpentSeconds),
      lat: null,
      lon: null,
      json: JSON.stringify({
        model: this.getBrowserModel(),
        height: window.innerHeight,
        width: window.innerWidth
      }),
      stato: 0,
      id: Math.floor(Math.random() * 100000)
    };

    const logs = this.getLocalLogs();
    logs.push(logEntry);
    this.saveLocalLogs(logs);

    this.syncStats();
  }

  updateSongSettings(idCanti: number, tonalita: number, speed: number = 0) {
    if (!this.settingsService.invioDatiStatistici()) return;

    console.log('📊 StatsService: updateSongSettings called for song', idCanti, 'tonalita:', tonalita);

    const settingsList = this.getLocalSongSettings();
    const idx = settingsList.findIndex(s => s.id_canti === idCanti);

    if (idx !== -1) {
      settingsList[idx].tonalita = tonalita;
      settingsList[idx].speed = speed;
    } else {
      settingsList.push({
        id_canti: idCanti,
        speed: speed,
        tonalita: tonalita,
        id: Math.floor(Math.random() * 100000)
      });
    }

    this.saveLocalSongSettings(settingsList);
    this.syncStats();
  }

  private clearLocalStats() {
    localStorage.removeItem('stats-logs-queue');
    localStorage.removeItem('stats-settings-queue');
  }

  syncStats() {
    if (!this.settingsService.invioDatiStatistici()) {
      console.log('📊 StatsService: Sync ignored (settings disabled)');
      return;
    }
    if (!this.connectivityService.isOnline()) {
      console.log('📊 StatsService: Sync postponed (offline)');
      return;
    }

    const logs = this.getLocalLogs();
    const settings = this.getLocalSongSettings();

    console.log('📊 StatsService: syncStats checking queues. Logs:', logs.length, 'Settings:', settings.length);

    if (logs.length === 0 && settings.length === 0) {
      return;
    }

    const uuid = this.getOrCreateUUID();
    const email = this.comunitaService.comunitaMail() || `pwa-${uuid.substring(0,8)}@librettocanti.it`;

    const payload = {
      uuid: uuid,
      log: logs,
      pref: [],
      canti_settings: settings,
      user_devices: {
        uuid: uuid,
        email: email,
        platform: 'browser',
        version: VERSION,
        gruppo: (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) ? this.comunitaService.comunitaCode() : '',
        all_song: false,
        deleteList: false,
        deletePref: false,
        data_app_sync: this.formatDateTime(new Date())
      }
    };

    const url = `https://api.librettocanti.it/canti/api/v1/updateOnlineDB?uuid=${uuid}&email=${email}`;
    console.log('📊 StatsService: Sending POST request to:', url, 'with payload:', payload);

    this.http.post(url, payload).subscribe({
      next: (res) => {
        this.clearLocalStats();
        console.log('📊 StatsService: Sync successful!', res);
      },
      error: (err) => {
        console.error('📊 StatsService: Sync failed, keeping in local buffer...', err);
      }
    });
  }
}
