import {
  AfterViewInit,
  Component,
  OnDestroy,
  OnInit,
  Renderer2,
} from '@angular/core';
import * as L from 'leaflet';
import 'leaflet.markercluster';
import { Subscription, take } from 'rxjs';
import { SocketService } from '../../../shared/services/socket.service';
import { MatDialog } from '@angular/material/dialog';
import { AlarmSoundService } from '../../../shared/services/alarm-sound.service';
import { CameraDialogComponent } from '../../../shared/component/camera-dialog/camera-dialog.component';
import { alarmData, alarmDemo } from '../data/fake-data';
import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service';

@Component({
  selector: 'app-centralized-security-management',
  templateUrl: './centralized-security-management.component.html',
  styleUrls: ['./centralized-security-management.component.scss'],
})
export class CentralizedSecurityManagementComponent
  implements OnInit, AfterViewInit, OnDestroy
{
  private map!: L.Map;
  private markers!: L.MarkerClusterGroup;
  private statusSubscription?: Subscription;
  private messageSubscription?: Subscription;
  data = alarmData;
  alarmDemo = alarmDemo;
  state1 = false;
  state2 = false;
  state5 = false;
  state6 = false;
  isReady = true;

  constructor(
    private socketService$: SocketService,
    private dialog: MatDialog,
    private renderer: Renderer2,
    private alarmSoundService$: AlarmSoundService,
  ) {}

  ngOnInit() {
    this.statusSubscription = this.socketService$.status$.subscribe(
      (isConnected) => {
        if (isConnected) {
          this.socketService$.sendMessage({ id: '0', type: 'get' });
          this.messageSubscription = this.socketService$.messages$.subscribe(
            (message) => {
              this.onMessage(message);
            },
          );
        }
      },
    );
  }

  openDialog(): void {
    this.dialog.open(CameraDialogComponent, {
      width: '80vw',
      data: '',
    });
  }

  ngAfterViewInit(): void {
    this.initMap();
  }

  ngOnDestroy(): void {
    this.statusSubscription?.unsubscribe();
    this.messageSubscription?.unsubscribe();
    this.socketService$.close();
    this.alarmSoundService$.stopAlarm();
  }

  initMap(): void {
    const mapContainer = document.getElementById('map');
    if (mapContainer) {
      this.map = L.map('map', {
        center: [10.7483, 106.7537],
        zoom: 12,
      });

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 15,
        minZoom: 3,
        attribution:
          '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
      }).addTo(this.map);

      this.addIconsToMap();
    } else {
      console.error('Map container not found');
    }
  }

  onMessage(message: any) {
    if (message.id == '0' && message.type === 'get') {
      this.state1 = message.state1 === '0'; // 1 OFF // alarm 12h
      this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h
      this.state5 = message.state5 === '1'; // 1 ON, 0 OFF
      this.isReady = message.ready === '1';
      this.alarmSoundService$.startAlarm(this.state5, this.isReady, this.state1, this.state2);
      this.updateIcons();

    }

  }

  addIconsToMap(): void {
    this.markers = L.markerClusterGroup();
    this.data.forEach((item) => this.addMarker(item));
    this.addMarker(this.alarmDemo, true);
    this.map.addLayer(this.markers);
  }

  addMarker(item: any, isDemo: boolean = false): void {
    const icon = isDemo
      ? this.getIcon(this.state5, this.isReady, this.state1, this.state2)
      : this.createIcon(item.warning);
    const marker = L.marker(
      [item.detail.coordinates.lat, item.detail.coordinates.lng],
      { icon },
    ).bindPopup(this.popupDetail(item));

    marker.on('popupopen', (event) => this.bindPopupEvents(event));

    this.markers.addLayer(marker);
  }

  bindPopupEvents(event: any): void {
    const popupContainer = event.popup.getElement();
    const button = popupContainer?.querySelector('.dynamic-button');
    if (button) {
      this.renderer.listen(button, 'click', () => this.openDialog());
    }
  }

  updateIcons(): void {
    this.markers.clearLayers();
    this.addIconsToMap();
  }

  popupDetail(item: any): string {
    return `
      <div class="tooltip" style="width: 200px">
        <div style="display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 5px">
          <div style="color: #F33152; padding: 5px 13px; background-color: rgba(243, 49, 82, 0.1); border-radius: 20px; text-align: center; max-width: 180px;">${item.title}</div>
          <a class="dynamic-button">
            <svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none">
              <g stroke="currentColor" stroke-width="2">
                <path d="M16 16V8a1 1 0 00-1-1H5a1 1 0 00-1 1v8a1 1 0 001 1h10a1 1 0 001-1z"/>
                <path stroke-linejoin="round" d="M20 7l-4 3v4l4 3V7z"/>
              </g>
            </svg>
          </a>
        </div>
        <div><strong>Địa điểm:</strong> ${item.detail.position}</div>
        <div><strong>Tọa độ:</strong> ${item.detail.coordinates.lat}, ${item.detail.coordinates.lng}</div>
        <div><strong>Thời gian:</strong> ${item.detail.time}</div>
        <a href="/overview/overall-ground" target="_blank">Xem chi tiết</a>
      </div>`;
  }

  createIcon(
    active: boolean,
    className: string = '',
    text: any = [],
  ): L.Icon<L.IconOptions> | L.DivIcon {
    if (text.length < 1) {
      return L.icon({
        iconUrl: active
          ? '../../../../assets/images/sensor-on.png'
          : '../../../../assets/images/sensor-off.png',
        iconSize: [30, 30],
        className: className,
      });
    } else {
      let htmlContent = '';
      text.forEach((item: any) => {
        htmlContent += `<span><b>${item}</b></span><br>`;
      });

      return L.divIcon({
        html: `<div class="icon">
                <div style="z-index:9999" class="sensor-on">
                  <img alt="icon-alarm" src="assets/images/sensor-on.png" style="width: 30px; height: 30px">
                </div>
                <div style="background: #F11E1E; color: #FFF; padding: 2px 3px; font-size: 11px; margin-top: 10px; text-align: center">
                  ${htmlContent}
                </div>
              </div>`,
        iconSize: [200, 30],
        className: className,
      });
    }
  }

  getIcon(
    isTurnOn: boolean,
    isReady: boolean,
    fireArm: boolean,
    fenceArm: boolean,
  ): L.Icon<L.IconOptions> | L.DivIcon {
    if (isTurnOn && isReady) {
      let text = [];
      if (fireArm && fenceArm) {
        text.push('FIRE ALARM', 'FENCE ALARM');
      } else if (fireArm) {
        text.push('FIRE ALARM');
      } else if (fenceArm) {
        text.push('FENCE ALARM');
      }
      return this.createIcon(true, '', text);
    }
    return this.createIcon(false);
  }
}
