import {Component, OnDestroy, OnInit} from '@angular/core';
import {Group} from '../../shared/api/endpoints/models/group';
import {Drivers} from '../../shared/api/endpoints/models/drivers';
import {GeneralInfo} from '../../shared/api/endpoints/models/general-info';
import {Lastpos} from '../../shared/api/endpoints/models/lastpos';
import {Sensor} from '../../shared/api/endpoints/models/sensor';
import {Unit} from '../../shared/api/endpoints/models/unit';
import {DataService} from '../../shared/api/endpoints/services/data.service';
import {Phenomenon} from '../../shared/api/endpoints/models/phenomenon';
import {SensorsService} from '../../shared/api/endpoints/services/sensors.service';
import {ConfirmationService, MenuItem, MessageService} from 'primeng/api';
import {ManagementService} from '../../shared/api/endpoints/services/management.service';
import {ToastService} from '../../shared/services/toast.service';
import {map} from 'rxjs/operators';
import {HttpClient, HttpResponse} from '@angular/common/http';
import {AuthService} from '../../auth/services/auth.service';
import {User} from '../../auth/models/user';
import {SensorType} from '../../shared/api/endpoints/models/sensor-type';
import {forkJoin, Subscription} from 'rxjs';
import {ActivatedRoute} from '@angular/router';
import {Config} from '../../shared/api/endpoints/models/config';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit, OnDestroy {

  loggedUser: User;
  position: 'bottom';
  groups: Group[];
  units: Array<{ drivers?: Drivers; generalInfo?: GeneralInfo; holder?: any; lastpos?: Lastpos; sensors?: Array<Sensor>; unit?: Unit }>;
  cstmUnits: Array<{ drivers?: Drivers; generalInfo?: GeneralInfo; holder?: any; lastpos?: Lastpos; sensors?: Array<Sensor>; unit?: Unit }>;
  editedUnit: Unit;
  showEditUnitPopup = false;
  showInsertSensorPopup = false;
  showInsertPositionPopup = false;
  // phenomenons: Phenomenon[];
  sensorTypes: SensorType[];
  subscription: Subscription[] = [];

  // 0 = Dashboard, 1 = Map view
  selectedTabIndex = 0;   // <-- set the default here

  constructor(
    private dataService: DataService,
    private sensorService: SensorsService,
    // private confirmationService: ConfirmationService,
    // private messageService: MessageService,
    // private managementService: ManagementService,
    private toastService: ToastService,
    private authService: AuthService,
    private route: ActivatedRoute,
    private http: HttpClient
  ) {
    this.initData();
  }

  ngOnInit(): void {
    const tab = this.route.snapshot.queryParamMap.get('tab');
    if (tab === 'map') {
      this.selectedTabIndex = 1;   // show Map view
    }
  }

  /**
   * Unsubscribe after leaving
   */
  ngOnDestroy(): void {
    this.subscription.forEach(subs => subs.unsubscribe());
  }

  /**
   * Get necessary data from backend
   */
  initData() {
    // this.sensorService.getPhenomenons().subscribe(
    //   response => this.phenomenons = response
    // );
    this.sensorService.getSensorTypes().subscribe(
      response => this.sensorTypes = response
    );
    this.setUser();
    this.getUnits();
  }

  /**
   * Get user from user state
   */
  setUser(){
    this.authService.getUserState().subscribe(res => {
      if(res){
        this.loggedUser = res;
      }
    });
  }

  /**
   * Get all units and theirs sensors from backend
   */
  getUnits() {
    forkJoin({
      masterData: this.dataService.getData(),
      config: this.http.get<Config>('assets/example.json')
    }).subscribe({
      next: ({ masterData, config }) => {
        console.log(masterData);

        // 1. Store and sort the raw master data
        this.units = masterData;
        this.units.forEach(u => u.sensors?.sort((a, b) => (a.sensorId ?? 0) - (b.sensorId ?? 0)));

        // 2. Extract configuration selections
        const { units: unitSelections, globalSensors } = config.preferences.selections;

        // 3. Perform the filtering logic
        this.cstmUnits = this.units.map(masterUnit => {

          // Find specific config for this unit
          const selection = unitSelections.find(u => u.unitId === masterUnit.unit?.unitId);

          const filteredSensors = (masterUnit.sensors || []).filter(sensor => {
            const sId = sensor.sensorId;
            if (sId === undefined) return false;

            const isGlobal = globalSensors.includes(sId);
            let isLocallySelected = false;

            if (selection) {
              isLocallySelected = selection.sensors === 'ALL' ||
                  (Array.isArray(selection.sensors) && selection.sensors.includes(sId));
            }

            return isGlobal || isLocallySelected;
          });

          // Return the unit structure with the new filtered sensor array
          return {
            ...masterUnit,
            sensors: filteredSensors
          };
        })
            // 4. Final step: Only keep units that have at least one valid sensor
            .filter(u => u.sensors.length > 0);

        console.log('Filtered cstmUnits:', this.cstmUnits);
      },
      error: (err) => {
        this.toastService.showError(err.error?.message || 'Error loading data');
      }
    });

    /*
    this.dataService.getData().subscribe(data => {
      this.units = data;
      this.units.forEach(unit => unit.sensors.sort((a, b) => a.sensorId - b.sensorId));

      // according to the config file filter through units
      this.cstmUnits = [this.units[0]];

      console.log(this.units);
      console.log(this.units[0].unit);
      console.log(this.units[0].sensors);
    }, err => this.toastService.showError(err.error.message));
     */
  }

  /**
   * Add created unit to memory so we do not need call backend
   * @param inserted unit
   */
  addUnit(inserted: any) {
    const sensors: Sensor[] = [];
    inserted.sensors.forEach(sens => {
      sensors.push({
        sensorId: sens.sensor_id,
        sensorType: sens.sensor_type,
        sensorName: sens.sensor_name,
        phenomenon: {
          phenomenonId: sens.phenomenon.phenomenon_id.toString()
        }
      })
    });
    this.units.push({
      unit: {
        unitId: inserted.unit.unit_id,
        description: inserted.unit.description
      },
      sensors
    })
  }

}
