//
//  SharingData.swift
//  forShip
//
//  Created by Mamoru Sugita on 2023/10/20.
//
import Foundation
import CoreLocation

enum EcaOperation {
    case Insert
    case Delete
    case Running
    case Notice
    case Start
    case Finish
    case End
    case Incomplete
    case Change
    case Cancel
}

class SharingData{
    
    static var my = My()
    class My: ObservableObject {
        @Published var id: Int = 0
        @Published var shipName: String = ""
        @Published var imo: Int = 0
        @Published var mmsi: Int = 0
        @Published var isUpDate: Bool = false

        @Published var ecaStatus: EcaState?

        var manualUrls: [ResGetManualUrl] = []
    }

    static var location = Location()
    class Location: ObservableObject {
        @Published var location: CLLocationCoordinate2D? = .init(latitude: 0, longitude: 0)
        @Published var gps: CLLocationCoordinate2D? = nil
        @Published var server: CLLocationCoordinate2D? = nil

        @Published var speed: Double = 0.0
        @Published var course: Double = 0.0
        @Published var heading: Double = 0.0
        @Published var dataTime: String = "" //2023-11-02T05:25:49.4362123Z

        func setLocation(){
            if Preferences.LocationType == 0 {
                self.location = self.gps
            } else {
                self.location = self.server
            }
        }

        func reset() {
            speed = 0.0
            course = 0.0
            heading = 0.0

            location = nil
        }
    }

    static var map = Map()
    class Map: ObservableObject {
        @Published var wayPoints: [CLLocationCoordinate2D] = []
        @Published var legLine: [CLLocationCoordinate2D] = []
        @Published var portLine: [CLLocationCoordinate2D] = []
        @Published var starboardLine: [CLLocationCoordinate2D] = []
    }

    static var message = Message()
    class Message: ObservableObject {
        @Published var mode: Int = 0   // 0:通常 , 1:Warning中
        @Published var messages: [ChatMessage] = []
    }

    /**
     * Eca
     */
    static var eca = Eca()
    class Eca: ObservableObject{
        @Published var ecaArea: Dictionary<String, RegisteredEca> = [:]
        @Published var focusEca: String? = nil
        @Published var isShowEcaAlert: Bool = false
        
        func setEcaArea(key: String, value: RegisteredEca) {
            ecaArea.updateValue(value, forKey: key)
        }

        func editEcaArea(key: String, value: RegisteredEca, type: EcaOperation) {
            let setEcaArea = SetEcaArea()
            var task = ReqTaskList(Id: value.id)

            switch type {
            case EcaOperation.Running:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                task.status = serverRunning
                setEcaArea.start(eca: task)
            case EcaOperation.Insert:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                task.status = serverRegister
                setEcaArea.start(eca: task)
            case EcaOperation.Delete:
                let deleteEcaArea = DeleteEcaArea()
                deleteEcaArea.start(ecaId: value.id)
            case EcaOperation.Notice:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable && value.isRunning {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            case EcaOperation.Start:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable && value.isRunning {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            case EcaOperation.Finish:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            case EcaOperation.End:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            case EcaOperation.Incomplete:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
           case EcaOperation.Cancel:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            case EcaOperation.Change:
                task.areaId = value.id
                task.taskName = value.name
                task.noticeRange = value.swNotice
                task.startRange = value.swStart
                task.finishRange = value.swFinish
                if value.isEnable && value.isRunning {
                    task.status = setEcaStatus(eca: value)
                }
                setEcaArea.start(eca: task)
            }
            ecaArea.updateValue(value, forKey: key)
        }

        private func setEcaStatus(eca: RegisteredEca) -> Int {
            var state = serverRegister
            switch eca.status {
            case EcaState.running:
                state = serverRunning
            case EcaState.noticePass:
                state = serverNoticePass
            case EcaState.startPass:
                state = serverStartPass
            case EcaState.finishPass:
                state = serverFinishPass
            case EcaState.end:
                state = serverEnd
            case EcaState.incomplete:
                state = serverIncomplete
            case EcaState.cancel:
                state = serverCancel
            default:
                state = serverRegister
            }

            return state
        }
    }

    static var pushHistory = PushHistory()
    class PushHistory: ObservableObject{
        @Published var pushHistoryData: Dictionary<Int, ResPushHistory> = [:]
        @Published var focusPushHistory: Int? = nil

        func setPushHistory(key: Int, value: ResPushHistory) {
            pushHistoryData.updateValue(value, forKey: key)
        }
    }

    static var noticeInformation = NoticeInformation()
    class NoticeInformation: ObservableObject {
    }
}
