import { __decorate, __metadata } from "tslib";
import { css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { PageView } from '@operato/shell';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import { fromLonLat } from 'ol/proj.js';
import 'ol/ol.css';
import { MVT } from 'ol/format';
import { VectorTile, XYZ } from 'ol/source';
import VectorTileLayer from 'ol/layer/VectorTile';
import { Style, Stroke } from 'ol/style';
import { TemperatureLayer, PrecipitationLayer, initializeWorkerSystem } from '@hyperviz/weather';
import { WindDataTileLayer } from '../ol-components/wind-data-tile-layer.js';
let WeatherPage = class WeatherPage extends PageView {
    static get styles() {
        return css `
      :host {
        display: flex;
        flex-direction: column;
        height: 100%;
      }

      .map-container {
        flex: 1;
        display: flex;
        position: relative;
        background-color: #f9f9f9;
        overflow: hidden;
      }

      #map {
        flex: 1;
      }

      .controls {
        position: absolute;
        top: 10px;
        right: 10px;
        display: flex;
        flex-direction: column;
        gap: 10px;
        background: rgba(255, 255, 255, 0.8);
        padding: 15px;
        border-radius: 4px;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        z-index: 10;
      }

      .weather-btn {
        cursor: pointer;
        padding: 8px 12px;
        background-color: #f0f0f0;
        border: 1px solid #ddd;
        border-radius: 4px;
        font-weight: bold;
        transition: all 0.3s;
      }

      .weather-btn.active {
        background-color: #4281f5;
        color: white;
        border-color: #2d5ed9;
      }

      .refresh-btn {
        margin-top: 10px;
        cursor: pointer;
        padding: 8px 12px;
        background-color: #00c851;
        color: white;
        border: none;
        border-radius: 4px;
        font-weight: bold;
        transition: all 0.3s;
      }

      .refresh-btn:hover {
        background-color: #00a651;
      }
    `;
    }
    constructor() {
        super();
        this.activeType = 'temperature';
        this.map = null;
        this.weatherLayer = null;
    }
    render() {
        return html `
      <div class="map-container">
        <div id="map"></div>

        <div class="controls">
          <button
            class="weather-btn ${this.activeType === 'temperature' ? 'active' : ''}"
            @click=${() => this._changeWeatherType('temperature')}
          >
            온도
          </button>
          <button
            class="weather-btn ${this.activeType === 'wind' ? 'active' : ''}"
            @click=${() => this._changeWeatherType('wind')}
          >
            바람
          </button>
          <button
            class="weather-btn ${this.activeType === 'precipitation' ? 'active' : ''}"
            @click=${() => this._changeWeatherType('precipitation')}
          >
            강수량
          </button>
          <button class="refresh-btn" @click=${this._refreshWeatherMap}>새로고침</button>
        </div>
      </div>
    `;
    }
    connectedCallback() {
        super.connectedCallback();
        initializeWorkerSystem();
        requestAnimationFrame(() => {
            this._initMap();
        });
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        if (this.weatherLayer) {
            try {
                this.weatherLayer.removeFromMap();
                this.weatherLayer.dispose();
            }
            catch (e) {
                console.error('Error disposing weather layer:', e);
            }
        }
        if (this.map) {
            this.map.dispose();
        }
        this.map = null;
        this.weatherLayer = null;
    }
    _initMap() {
        const lightOSM = new TileLayer({
            source: new XYZ({
                url: 'https://{a-c}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png',
                attributions: '© OpenStreetMap contributors, © CartoDB'
            }),
            background: 'transparent',
            opacity: 1
        });
        const labelOSM = new TileLayer({
            source: new XYZ({
                url: 'https://{a-c}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png'
            }),
            background: 'transparent',
            opacity: 1
        });
        const vectorTile = new VectorTile({
            format: new MVT({
                layerName: 'countries',
                layers: ['countries']
            }),
            url: `/geo/tiles/{z}/{x}/{y}.mvt`,
            maxZoom: 10,
            projection: 'EPSG:3857'
        });
        const outlineLayer = new VectorTileLayer({
            source: vectorTile,
            style: new Style({
                stroke: new Stroke({
                    color: '#858585',
                    // color: '#484848',
                    width: 1
                })
            })
        });
        this.map = new Map({
            target: this.renderRoot.querySelector('#map'),
            pixelRatio: Math.min(window.devicePixelRatio, 2),
            layers: [lightOSM, outlineLayer, labelOSM],
            view: new View({
                center: fromLonLat([126.9779692, 37.5662952]),
                zoom: 5
            })
        });
        this._addWeatherLayer();
    }
    _addWeatherLayer() {
        if (!this.map)
            return;
        switch (this.activeType) {
            case 'temperature':
                this.weatherLayer = new TemperatureLayer();
                break;
            case 'wind':
                this.weatherLayer = new WindDataTileLayer();
                break;
            case 'precipitation':
                this.weatherLayer = new PrecipitationLayer();
                break;
            default:
                this.weatherLayer = new TemperatureLayer();
        }
        if (this.weatherLayer) {
            this.weatherLayer.addToMap(this.map);
        }
    }
    /**
     * 날씨 레이어를 변경하고 새 레이어를 맵에 추가
     */
    _changeWeatherType(type) {
        if (this.activeType === type)
            return;
        // 현재 활성 타입 저장
        const previousType = this.activeType;
        // 새로운 타입으로 변경
        this.activeType = type;
        console.log(`날씨 타입 변경 시작: ${previousType} -> ${type}`);
        // 이전 레이어가 있을 경우 처리
        if (this.map && this.weatherLayer) {
            // 맵 참조 저장
            const mapRef = this.map;
            // 이전 레이어 참조 저장
            const oldLayer = this.weatherLayer;
            // 렌더링 참조 제거
            this.weatherLayer = null;
            // 이전 레이어 제거 처리
            try {
                console.log(`이전 레이어(${previousType}) 제거 시작`);
                // 1. 레이어 시각적으로 즉시 숨김 (특히 WindDataTileLayer 경우 중요)
                if (previousType === 'wind') {
                    if (oldLayer['layer'] && typeof oldLayer['layer'].setVisible === 'function') {
                        oldLayer['layer'].setVisible(false);
                    }
                }
                // 2. 컴포넌트에서 참조 제거 (렌더링 사이클에서 제외)
                this.weatherLayer = null;
                // 3. 비동기 처리: 렌더링 사이클이 완료된 후 실행
                requestAnimationFrame(() => {
                    setTimeout(() => {
                        try {
                            // 레이어 참조가 남아있을 경우에만 제거 시도
                            if (oldLayer) {
                                oldLayer.removeFromMap();
                                // 약간의 지연 후 자원 해제
                                setTimeout(() => {
                                    try {
                                        oldLayer.dispose();
                                        console.log(`이전 레이어(${previousType}) 완전히 제거됨`);
                                    }
                                    catch (e) {
                                        console.warn('레이어 리소스 해제 중 오류:', e);
                                    }
                                    // 새 레이어 생성 시작
                                    this._addNewLayer(type, mapRef);
                                }, 50); // dispose 지연
                            }
                            else {
                                // 레이어 참조가 없는 경우 즉시 새 레이어 생성
                                this._addNewLayer(type, mapRef);
                            }
                        }
                        catch (e) {
                            console.error('레이어 제거 중 오류 발생:', e);
                            // 오류 발생해도 새 레이어 생성 시도
                            this._addNewLayer(type, mapRef);
                        }
                    }, 100); // 레이어 제거 지연
                });
            }
            catch (e) {
                console.error('레이어 전환 중 오류:', e);
                // 에러 상태에서도 새 레이어 추가 시도
                this._addNewLayer(type, mapRef);
            }
        }
        else {
            // 기존 레이어가 없으면 바로 새 레이어 추가
            this._addWeatherLayer();
        }
    }
    /**
     * 새 레이어를 안전하게 추가하는 헬퍼 메소드
     */
    _addNewLayer(type, mapRef) {
        // 타입이 바뀌지 않았는지 확인
        if (this.activeType !== type) {
            console.log(`타입이 변경되어 레이어 생성 취소: ${this.activeType}로 변경됨`);
            return;
        }
        console.log(`새 레이어(${type}) 생성 시작`);
        try {
            // 맵 참조 확인
            if (!this.map && mapRef) {
                this.map = mapRef;
            }
            if (this.map) {
                // 새 레이어 생성 및 맵에 추가
                this._addWeatherLayer();
                console.log(`새 레이어(${type}) 생성 완료`);
            }
            else {
                console.error('맵 참조 없음: 레이어를 추가할 수 없습니다');
            }
        }
        catch (e) {
            console.error('새 레이어 생성 중 오류:', e);
        }
    }
    _refreshWeatherMap() {
        if (this.weatherLayer) {
            try {
                // 타입에 따라 적절한 메서드 호출
                if (this.activeType === 'wind') {
                    ;
                    this.weatherLayer.updateLayer();
                }
                else {
                    // @hyperviz/weather 레이어
                    ;
                    this.weatherLayer.setWeatherData([]);
                }
            }
            catch (e) {
                console.error('Error refreshing weather layer:', e);
            }
        }
    }
};
__decorate([
    property({ type: String }),
    __metadata("design:type", Object)
], WeatherPage.prototype, "activeType", void 0);
__decorate([
    state(),
    __metadata("design:type", Object)
], WeatherPage.prototype, "map", void 0);
__decorate([
    state(),
    __metadata("design:type", Object)
], WeatherPage.prototype, "weatherLayer", void 0);
WeatherPage = __decorate([
    customElement('weather-page'),
    __metadata("design:paramtypes", [])
], WeatherPage);
export { WeatherPage };
//# sourceMappingURL=weather-page.js.map