//
//  MapViewController.swift
//  BookCore
//
//  Created by 日々野清高 on 2023/01/19.
//

import Foundation
import UIKit
import MapKit
import PlaygroundSupport
import AVFoundation
import CoreLocation

public class MapViewController: UIViewController, MKMapViewDelegate, PlaygroundLiveViewSafeAreaContainer  {
    private var mapView = MKMapView()
    private var annotationColor = UIColor()
    private var pinIsStar = false
    private var pinIsKiki = false
    var audioPlayer: AVAudioPlayer? //ウォームアップ用
    
    public required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    // 初期表示を設定する関数
    func setupInitialMapView() {
        let initialLocation = CLLocationCoordinate2D(latitude: 35.22509, longitude: 137.40516) // 初期位置
        let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005) // ズームの範囲
        let region = MKCoordinateRegion(center: initialLocation, span: span)
        // アニメーション付きでズームイン
        mapView.setRegion(region, animated: true)
    }
    
    func warmUpAudioSystem() { //サウンドのウォームアップ
        guard let soundURL = Bundle.main.url(forResource: "correct_male", withExtension: "mp3") else { return }
        do {
            let player = try AVAudioPlayer(contentsOf: soundURL)
            player.volume = 0.0 // 無音で再生
            player.play()
            audioPlayer = player
        } catch {
            print("音声のウォームアップに失敗: \(error)")
        }
    }
    
    public override func viewDidLoad() {
        super.viewDidLoad()
        warmUpAudioSystem()
        annotationColor = .black
        view.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
        // disable auto layout
        view.translatesAutoresizingMaskIntoConstraints = false
        
        // 緯度・軽度を設定
        let location:CLLocationCoordinate2D
            = CLLocationCoordinate2DMake(35.22509,137.40516)
        mapView.setCenter(location,animated:true)
 
        // 縮尺を設定
        var region:MKCoordinateRegion = mapView.region
        region.center = location
        region.span.latitudeDelta = 10
        region.span.longitudeDelta = 10
        mapView.setRegion(region,animated:true)
 
        // 少し遅れてズームインアニメーションを開始
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.setupInitialMapView()
        }
        
        // 表示タイプを航空写真と地図のハイブリッドに設定
        //mapView.mapType = MKMapType.standard
        // mapView.mapType = MKMapType.hybrid
        mapView.mapType = MKMapType.satellite
        view.addSubview(mapView)
        
        //mapView.isUserInteractionEnabled = true
        mapView.delegate = self
        mapView.clipsToBounds = true //はみ出さない様にする。
        //mapView.backgroundColor  = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
        mapView.layer.cornerRadius = 10
        mapView.translatesAutoresizingMaskIntoConstraints  = false
        mapView.topAnchor.constraint(equalTo: liveViewSafeAreaGuide.topAnchor, constant: 40).isActive = true
        mapView.bottomAnchor.constraint(equalTo: liveViewSafeAreaGuide.bottomAnchor, constant: -40).isActive = true
        mapView.leadingAnchor.constraint(equalTo: liveViewSafeAreaGuide.leadingAnchor, constant: 20).isActive = true
        mapView.trailingAnchor.constraint(equalTo: liveViewSafeAreaGuide.trailingAnchor, constant: -20).isActive = true
        mapView.showsCompass = true
        self.mapView.showsTraffic = true
    }
    
    //アノテーションを返すメソッド
    public func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        if let myAnnotation = annotation as? MyPointAnnotation {
            if myAnnotation.isStar {
                // ★星のアノテーション（カスタム画像）
                let identifier = "starAnnotation"
                var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

                if annotationView == nil {
                    annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                    annotationView?.canShowCallout = true
                    annotationView?.isDraggable = true
                    annotationView?.clusteringIdentifier = nil
                    annotationView?.centerOffset = CGPoint(x: 0, y: -10)
                } else {
                    annotationView?.annotation = annotation
                }

                annotationView?.image = UIImage(named: "annotationStar.png")
                addSparkleEffect(to: annotationView)
                return annotationView
            }
            if myAnnotation.isKiki {
                // キキのアノテーション（カスタム画像）
                let identifier = "kikiAnnotation"
                var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

                if annotationView == nil {
                    annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                    annotationView?.canShowCallout = true
                    annotationView?.isDraggable = true
                    annotationView?.clusteringIdentifier = nil
                    annotationView?.centerOffset = CGPoint(x: 0, y: -10)
                } else {
                    annotationView?.annotation = annotation
                }

                annotationView?.image = UIImage(named: "annotationKIKI.png")
                // アニメーション（サイズをポンっと拡大）
                annotationView?.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
                UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
                    annotationView?.transform = .identity
                }, completion: nil)
                return annotationView
            }
            // 通常のアノテーション（標準マーカー）
            let identifier = "markerAnnotation"
            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView
            
            if annotationView == nil {
                annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                annotationView?.canShowCallout = true
                annotationView?.isDraggable = true
                annotationView?.clusteringIdentifier = nil
                annotationView?.animatesWhenAdded = true
            } else {
                annotationView?.annotation = annotation
            }
            
            annotationView?.markerTintColor = myAnnotation.tintColor
            return annotationView
        }

        return nil
    }

    // キラキラエフェクトを追加するメソッド
    func addSparkleEffect(to annotationView: MKAnnotationView?) {
        guard let annotationView = annotationView else { return }

        let sparkleLayer = CAEmitterLayer()
        sparkleLayer.emitterPosition = CGPoint(x: annotationView.bounds.width / 2, y: annotationView.bounds.height / 2)
        sparkleLayer.emitterShape = .point
        sparkleLayer.renderMode = .additive
        
        guard let sparkleImage = UIImage(named: "star.png") else { return }
        
        let cell = CAEmitterCell()
        cell.contents = sparkleImage.cgImage
        cell.birthRate = 3
        cell.lifetime = 1.2
        cell.velocity = 30
        cell.velocityRange = 15
        cell.scale = 0.5
        cell.scaleRange = 0.1
        cell.alphaSpeed = -0.4
        cell.emissionRange = .pi * 2  // 放射状に広がる
        cell.yAcceleration = 0  // 重力なし
        sparkleLayer.emitterCells = [cell]
        annotationView.layer.addSublayer(sparkleLayer)
    }
}

class MyPointAnnotation : MKPointAnnotation {
    var tintColor: UIColor?
    var isStar: Bool = false  // 星のアノテーションかどうかを示すフラグ
    var isKiki: Bool = false  // アノテーションをKiKiにするフラグ
}


extension MapViewController: PlaygroundLiveViewMessageHandler {
    //Playgroundページからメッセージを受け取る際の処理。
    public func receive(_ message: PlaygroundValue) {

        if case let .string(text) = message {
            if(text == "clear") { //クリア命令
                let allAnnotations = mapView.annotations
                mapView.removeAnnotations(allAnnotations)
                return
            }
            if(text == "standard") { //リセット用
                pinIsStar = false
                pinIsKiki = false
                return
            }
            if(text == "star") { //星にする
                pinIsStar = true
                return
            }
            if(text == "kiki") { //キキにする
                pinIsKiki = true
                return
            }
            //スペース区切りで引数を配列にセット
            let arr:[String] = text.components(separatedBy: " ")

            if(arr.count == 2) {
                if(arr[0] == "color") {
                    let cnumber = Int(arr[1])
                    if(cnumber == 0) {
                        annotationColor = .black
                    } else if (cnumber == 1) {
                        annotationColor = .systemRed
                    } else if (cnumber == 2) {
                        annotationColor = .systemOrange
                    } else if (cnumber == 3) {
                        annotationColor = .systemYellow
                    } else if (cnumber == 4) {
                        annotationColor = .systemGreen
                    } else if (cnumber == 5) {
                        annotationColor = .systemBlue
                    } else if (cnumber == 6) {
                        annotationColor = .systemIndigo
                    } else if (cnumber == 7) {
                        annotationColor = .systemPurple
                    }
                    return
                }
                if(arr[0] == "type") {
                    let ynumber = Int(arr[1])
                    if(ynumber == 0) {
                        mapView.mapType = MKMapType.standard
                    } else {
                        mapView.mapType = MKMapType.hybrid
                    }
                    return
                }
            }
            if(arr.count == 4) {
                if(arr[0] == "mark") {
                    let title = arr[1]
                    let latitude = Double(arr[2])!
                    let longitude = Double(arr[3])!
                    let coordinate = CLLocationCoordinate2DMake(latitude, longitude)
                    let pin = MyPointAnnotation()
                    pin.coordinate = coordinate
                    pin.title = title
                    pin.tintColor = annotationColor
                    pin.isStar = pinIsStar
                    pin.isKiki = pinIsKiki
                    mapView.addAnnotation(pin)
                }
                return
            }

            if(arr.count == 5 ){
                if(arr[0] == "color") { //色指定命令
                    let r = CGFloat(Double(arr[1])!)
                    let g = CGFloat(Double(arr[2])!)
                    let b = CGFloat(Double(arr[3])!)
                    let a = CGFloat(Double(arr[4])!)
                    annotationColor = UIColor(red: r, green: g, blue: b, alpha: a)
                }
            }
    }
    }
   //Playgroundページにメッセージを送る際のサンプル。
    //public func tapped() {
    //    let message: PlaygroundValue = .string("Hello!")
        //myTextView.insertText("[send to your code]Hello!\n")
    //    send(message)
   // }
}
