//
//  DataStorage.swift
//  Em-call
//
//  Created by Alex Sh on 04.04.2022.
//
//import Foundation
import UIKit
import CoreData


let Numbers:[String] = ["zero", "one", "two","three","four","five","six","seven","eight","nine","ten"]
   /* 11 eleven    12 twelve    13 thirteen    14 fourteen    15 fifteen    16 sixteen    17 seventeen    18 eighteen    19 nineteen
    20 twenty    21 twenty-one    22 twenty-two    30 thirty    40 forty    50 fifty    60 sixty    70 seventy    80 eighty
    90 ninety    100 one hundred*/

struct Profile {
    var name:String = String()
    var e_mail:String = String()
    var contactPhone:String = String()
    var card:String = String()
}
struct Electric {
    var workLocation:String = String()
    var dateAndTime:NSDate = NSDate()
    var contactPhone:String = String()
    var card:String = String()
}
struct Plumber {
    var workLocation:String = String()
    var dateAndTime:NSDate = NSDate()
    var contactPhone:String = String()
    var card:String = String()
}
struct Handyman {
    var workLocation:String = String()
    var dateAndTime:NSDate = NSDate()
    var contactPhone:String = String()
    var card:String = String()
}
struct Place {
    var placeHome:String = String()
    var placeHomeElectric:String = String()
    var placeHomePlumber:String = String()
    var placeHomeHandyman:String = String()
    var placeHomeLocksmith:String = String()
    var coordHome = (latitude:0.00000000,longitude:0.00000000)
    var coordPlumberCur = (latitude:0.00000000,longitude:0.00000000)
    var coordElectricCur = (latitude:0.00000000,longitude:0.00000000)
    var coordHandymanCur = (latitude:0.00000000,longitude:0.00000000)
    var coordLocksmithCur = (latitude:0.00000000,longitude:0.00000000)
}
struct ListWorkType {
    var listWorkTypeElectric:[String] =  Array()
    var listWorkTypePlumber:[String] =  Array()
    var listWorkTypeHandyman:[String] =  Array()
}
struct ListImageGalery {
    var listNameElectricImageGalery:[Int:String] = Dictionary()
    var listNamePlumberImageGalery:[Int:String] = Dictionary()
    var listNameHandymanImageGalery:[Int:String] = Dictionary()
    
    var listElectricImageGalery:[Int:UIImage] = Dictionary()
    var listPlumberImageGalery:[Int:UIImage] = Dictionary()
    var listHandymanImageGalery:[Int:UIImage] = Dictionary()
}

class DataStorage: NSObject {
    var Electrician_1: [NSManagedObject] = []
    var appDelegate = UIApplication.shared.delegate as? AppDelegate
    var firstRun = false
    var listMessageChat:[(String?,String?)] = Array()
    var listImageGalery = ListImageGalery()
   // var namePlaceMap:String = String()
    var listWorkType = ListWorkType()
    var handyman:Handyman = Handyman()
    var plumber:Plumber = Plumber()
    var electric:Electric = Electric()
    var place:Place = Place()
    var profile = Profile()
    var dataStrArray = [Data]()
    var imgNSData:[Data] = [Data]()
    var imgNSName:[Data] = [Data]()
   // let strArrayTransformer = StringArrayTransformer(coder: <#NSCoder#>)
   // let NSArrayTransformer = NSArrayValueTransformer()
    var strNSData:Data = Data()
    var imageNSData:Data = Data()
    var imgName:[String] = NSArray() as! [String]
    var imgData:[UIImage] = NSArray() as! [UIImage]
    
    override init() {
        super.init()
        /*
        //let managedContext = appDelegate?.persistentContainer.viewContext
         let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "imageProperty")

         do {
            guard let managedContext = appDelegate?.persistentContainer.viewContext
            else {
                return
            }
            imageProperty = try managedContext.fetch(fetchRequest)
         } catch let error as NSError {
           print("Could not fetch. \(error), \(error.userInfo)")
         }
         */
        load()
    }
    
    func getImageArray(flag:Int)->[UIImage] {
        var am:[UIImage] = [UIImage]()
        switch flag {
        case 0:    //Electric
            for item in listImageGalery.listElectricImageGalery {
                am.append(item.value)
            }
        default:
            return am
        }
        return am
    }
    
    func checkFirstRun() {
        firstRun = readBool(vbool:"firstRun")
        if firstRun == false {
            writeBool(vb:"firstRun")
         }
    }
    func writeBool(vb:String) {        //let vb:Bool = false
        let defaults = UserDefaults()
        defaults.set(true, forKey: vb)        //return vb
    }
    func readBool(vbool:String)->Bool {
        var vb:Bool = false
        let defaults = UserDefaults()
        vb = defaults.bool(forKey: vbool)
               return vb
    }
//-----------------------------------------------------------------------------------------------------
    func loadNSData()
    {
         imgNSData.removeAll()
         imgNSName.removeAll()
       // var strNSData:Data = Data()
       // var imageNSData:Data = Data()
        //strNSData.removeAll()
        // arrayImgNSData.removeAll()       // var dataStrArray = [Data]()
        dataStrArray.removeAll()
        for data in Electrician_1 as! [NSManagedObject] {
            imageNSData = data.value(forKey: "imgData") as! Data
            
        }
                      //arrayImgNSData - одна большая Data
        for data in Electrician_1 as! [NSManagedObject] {
            strNSData=data.value(forKey: "imgName") as! Data
      }
              //fetch image using decoding
       // imgNSData = arrayImgNSData
       // var dataArray = [Data]()
        //let imgDataArray = (try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: imageNSData))!
       // for imageData in imageNSData {
         /*   do {
                imgNSData = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: imageNSData) as! [Data]
               // dataArray.append(contentsOf: dataArray)
              } catch {
                print("could not unarchive array: \(error)")
              }*/
      ////  var Object:NSData = imageNSData
      /*  do {
            Object = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSData.self, from: imageNSData)!
        } catch {
            print("could not unarchive array: \(error)")
          }*/
      //  guard let object = Object else { return  }
        if let dataArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: imageNSData as Data) {
                for data in dataArray {
                    if let data = data as? Data, let image = UIImage(data: data) {
                        imgData.append(image)
                    }
                }
            }
        else {
            print("could not unarchive array")
        }
      /*  do {
            Object = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSData.self, from: strNSData)!
        } catch {
            print("could not unarchive array: \(error)")
          }*/
        //guard let o_bject = Object else { return  }
       /* if let dataArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: strNSData as Data) {
                for data in dataArray {
                    if let data = data as? Data, let image = NSString(data: data, encoding: <#UInt#>) {
                        imgData.append(image)
                    }
                }
            }*/
            //var dataArray = Data()
          /*  do {
               // let img = (try NSKeyedUnarchiver.unarchivedObject(ofClass: UIImage.self, from: imageData))!
               // let data = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSData.self, from: imageData) as! Data
                    imgNSData.append( imageData )    //dataArray, imgNSData - массив Data
                //imgData.append(contentsOf: img)
               // imgData.append(img as UIImage)
            } catch {
                print("could not unarchive array: \(error)")    }
        }*/
     /*   arrayImgNSData.forEach { (imageData) in   var dataArray = [Data]()
            do {     dataArray = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: imageData) as! [Data]
          imgNSData.append(contentsOf: dataArray)    //dataArray, imgNSData - массив Data
      } catch {      print("could not unarchive array: \(error)")    }      }         */
       // dataStrArray = arrayStrNSData
       // for imageName in arrayStrNSData {
        
        
        /*
            do {
               // let str = (try NSKeyedUnarchiver.unarchivedObject(ofClass: NSString.self, from: imageName))!
               dataStrArray = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: strNSData) as! [Data]
             // let  data = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSData.self, from: imageName) as! Data
               // imgName.append(str as String)
               // dataStrArray.append( imageName)    //dataArray, imgNSData - массив Data
            } catch {
                print("could not unarchive array: \(error)")    }
        */
        
        
       // }
       /* arrayStrNSData.forEach { (imageName) in     do {
                dataStrArray = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: imageName) as! [Data]
                    // imgNSData.append(contentsOf: dataArray)    //dataArray, imgNSData - массив Data
                } catch {             print("could not unarchive array: \(error)")    }        }*/
    }
//--------------------------------------------------------------------------------------------
    func getElectrician_1() {
        appDelegate = UIApplication.shared.delegate as? AppDelegate
        guard let managedContext = appDelegate?.persistentContainer.viewContext
        else {
            return
        }               // let managedContext = appDelegate.persistentContainer.viewContext
          let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Electrician_1")
          do {
             Electrician_1 = try managedContext.fetch(fetchRequest)
          } catch let error as NSError {
            print("Could not fetch. \(error), \(error.userInfo)")
            return
          }
    }
//--------------------------------------------------------------------------------------------
    func load()->Int {
        getElectrician_1()
                    // var imgName:[String] = NSArray() as! [String]
       let count = Electrician_1.count
        if count == 0 {
            return 0
        }
      //  var index = 0
        var imgName:[String] = NSArray() as! [String]
        var imgData:[UIImage] = NSArray() as! [UIImage]
        imgNSData.removeAll()
        imgNSName.removeAll()

      // arrayStrNSData.removeAll()
      //  arrayImgNSData.removeAll()       // var dataStrArray = [Data]()
       dataStrArray.removeAll()
            if appDelegate?.sim == 1 {
                                    // var i = 0                //  for data in Electrician_1 {
                   /*   let stringes = data.value(forKey: "imgName")    //  imgName = strArrayTransformer.reverseTransformedValue(stringes) as! [String]
                    arrayStrNSData  = strArrayTransformer.reverseTransformedValue(stringes) as! NSArray as? [NSData]
                                let images = data.value(forKey: "imgData")
                              //  imgData = NSArrayTransformer.reverseTransformedValue(images) as! [UIImage]
                    arrayImgNSData  = NSArrayTransformer.reverseTransformedValue(images) as! NSArray as? [NSData]*/  //массив NSData
                               /* i=0     for element in stringes {      imgName.append(element)
                                    listImageGalery.listNameElectricImageGalery.updateValue(element , forKey: i)
                                    i = i+1   }   i=0     for element in images {     imgData.append(element)
                                    listImageGalery.listElectricImageGalery.updateValue(element , forKey: i)   i = i+1
                                  }*/                           // index = index + 1
                loadNSData()
           }
        for strData in dataStrArray {
            let str = self.reverseTransformedValueStr( strData)
                if str != nil {
                imgName.append(str as! String)
                }
            }
        var i = 0
        for str in imgName {
            listImageGalery.listNameElectricImageGalery.updateValue(str, forKey: i)
            i=i+1
        }
        for imageData in imgNSData {
             let image = reverseTransformedValue( imageData)
                if image != nil {
                    imgData.append(image as! UIImage)
                }
            }
        i=0
          for img in imgData {
              listImageGalery.listElectricImageGalery.updateValue(img, forKey: i)
              i=i+1
          }
     /*   var coreDataArray = NSArray()
     for image in imgData {
         let provider:CGDataProvider = image.cgImage!.dataProvider!;
         let data:NSData = provider.data!;
        // let data: Data = NSData(image)
         coreDataArray.adding(data)
         }*/
      /*  for (key, value) in listImageGalery.listNameElectricImageGalery {
           // imgName.append(value)
            key = i
            value = imgName[i]
            i = i+1
        }*/
        return count
    }
 //-------------------------------------------------------------------------------------------------------------
    func save(imageData:UIImage,name: String,flagWorker:Int) {
        /*
         Трансформируемые атрибуты являются неизменяемым типом, поэтому их нельзя изменить.
         Единственный способ изменить их — создать новый объект и снова сохранить его в основных данных.
         */
        appDelegate = UIApplication.shared.delegate as? AppDelegate
        guard let managedContext = appDelegate?.persistentContainer.viewContext
        else {
            print("Could not make managedContext.")
            return
        }                // let set = company.mutableSetValue(forKey: "employee")
                // open class func insertNewObject(forEntityName entityName: String, into context: NSManagedObjectContext) -> NSManagedObject
                //let electric = NSEntityDescription.insertNewObject(forEntityName: "Electrician_1", into: managedContext)
        var fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Electrician_1")
        do {
           Electrician_1 = try managedContext.fetch(fetchRequest)
        } catch let error as NSError {
          print("Could not fetch. \(error), \(error.userInfo)")
          return
        }
      //  var imgName:[String] = NSArray() as! [String]
      //  var imgData:[UIImage] = NSArray() as! [UIImage]
      /*  let strArrayTransformer = StringArrayTransformer()
        let NSArrayTransformer = NSArrayValueTransformer()*/
        
        let count = Electrician_1.count
      if count == 0 {
       // let electric/*:NSManagedObject*/ = NSEntityDescription.insertNewObject(forEntityName: "Electrician_1", into: managedContext)
       //// let cmsg = NSManagedObject(entity: fetchRequest, insertInto: managedContext) as! Electrician_1
       //// let mRanges = Ranges(ranges: rangeArrays)
                        //// cmsg.setValue(mRanges, forKeyPath: "range")
            let electric/*:NSManagedObject*/ = NSEntityDescription.insertNewObject(forEntityName: "Electrician_1", into: managedContext)
            Electrician_1.append(electric) //= NSEntityDescription.insertNewObject(forEntityName: "Electrician_1", into: managedContext)
            imgName.append(name)
            imgData.append(imageData)
        // массив, который будет храниться в Core Data
        var coreDataArray = [NSData]()
        for image in imgData {
            let provider:CGDataProvider = image.cgImage!.dataProvider!;
            let data:NSData = provider.data!;
           // let data: Data = NSData(image)
            coreDataArray.append(data)
            }
        var strCoreDataArray = [NSData]()
        for str in imgName {
            let data: NSData = str.data(using: .utf8)! as NSData
            strCoreDataArray.append(data)
            }
        //to store array of images using encoding
      var images: Data?
        do {
            images = try NSKeyedArchiver.archivedData(withRootObject: coreDataArray, requiringSecureCoding: true)
        } catch {
            print("error")
        }
      // Electrician_1[0].setValue(images, forKeyPath: "imgData")
        Electrician_1[0].setValue(imgData, forKeyPath: "imgData")
        //Electrician_1[0].setValue(coreDataArray, forKeyPath: "imgData")
        var stringes: Data?
        do {
            stringes = try NSKeyedArchiver.archivedData(withRootObject: strCoreDataArray, requiringSecureCoding: true)
        } catch {
            print("error")
        }
        Electrician_1[0].setValue(stringes, forKeyPath: "imgName")
       // Electrician_1[0].setValue(strCoreDataArray, forKeyPath: "imgName")
               /*    // let dataImgName = strArrayTransformer.transformedValue(imgName)
        let dataImgName = strArrayTransformer.transformedValue(strCoreDataArray)
        let dataImgData = NSArrayTransformer.transformedValue(coreDataArray)
        Electrician_1[0].setValue(dataImgName, forKey: "imgName")
       // Electrician_1[0].setValue(strCoreDataArray, forKey: "imgName")
        Electrician_1[0].setValue(dataImgData, forKey: "imgData")
                        // Electrician_1[0].setValue(coreDataArray, forKey: "imgData")*/
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }
        return
      }
    // var index = 0   /// var arrayStrNSData:[Data] = [Data]()       // var arrayImgNSData:[Data] = [Data]()
        
          if appDelegate?.sim == 1
          {
            loadNSData()
          }
            for strData in dataStrArray {
                let str = self.reverseTransformedValueStr( strData)
                if str != nil {
                    imgName.append(str as! String)
                }
            }
                // imgName.append(name)
        var strCoreDataArray = [NSData]()
        for str in imgName {
            let data: NSData = str.data(using: .utf8)! as NSData
            strCoreDataArray.append(data)
            }
        // массив, который будет храниться в Core Data
         //  var coreDataArray = NSArray()
       for imageData in imgNSData {
             let image = reverseTransformedValue( imageData)
                if image != nil {
                    imgData.append(image as! UIImage)
                }
            }
        var coreDataArray = [NSData]()
     for image in imgData {
         let provider:CGDataProvider = image.cgImage!.dataProvider!;
         let data:NSData = provider.data!;
        // let data: Data = NSData(image)
         coreDataArray.append(data)
         }
       // imgData.append(imageData)
           //let electric = NSEntityDescription.entity(forEntityName: "Electrician_1", in: managedContext)!
       // var nameArray:[String] = NSArray() as! [String]
       // var imgArray:[UIImage] = NSArray() as! [UIImage]
                // let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Electrician_1")
    /*  fetchRequest        //:NSFetchRequest<NSFetchRequestResult>*
        = NSFetchRequest.init(entityName: "Electrician_1")
        do {
            let test = try managedContext.fetch(fetchRequest)
            if test.count == 0 {
                return
            }
            let objectUpdate = test[0]
            let stringes = strArrayTransformer.transformedValue(strCoreDataArray)
            let images = NSArrayTransformer.transformedValue(coreDataArray)
            objectUpdate.setValue(stringes, forKey: "imgName")
          //  objectUpdate.setValue(strCoreDataArray, forKey: "imgName")
             objectUpdate.setValue(images, forKey: "imgData")
           // objectUpdate.setValue(coreDataArray, forKey: "imgData")
            */
            //to store array of images using encoding
           var images: Data?
            do {
                images = try NSKeyedArchiver.archivedData(withRootObject: coreDataArray, requiringSecureCoding: true)
            } catch {
                print("error")
            }
          Electrician_1[0].setValue(images, forKeyPath: "imgData")
                //Electrician_1[0].setValue(coreDataArray, forKeyPath: "imgData")
           var stringes: Data?
            do {
                stringes = try NSKeyedArchiver.archivedData(withRootObject: strCoreDataArray, requiringSecureCoding: true)
            } catch {
                print("error")
            }
           Electrician_1[0].setValue(stringes, forKeyPath: "imgName")
                //Electrician_1[0].setValue(strCoreDataArray, forKeyPath: "imgName")
       // }
       // catch let error as NSError {
       //  print("Could not save managedContext. \(error), \(error.userInfo)")
       // }
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }
    }
//------------------------------------------------------------------------------------------------------
     public func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let data = value as? NSData else { return nil }
        do {
            let img = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIImage.self, from: data as Data)
            return img
        } catch {
            assertionFailure("Failed to transform `Data` to `NSArray` ")
            return nil
        }
    }
    //------------------------------------------------------------------------------------------------------
         public func reverseTransformedValueStr(_ value: Any?) -> Any? {
            guard let data = value as? NSData else { return nil }
           // do {
                let str = String(decoding: data, as: UTF8.self)
               // let str = try NSKeyedUnarchiver.unarchivedObject(ofClass: String.self, from: data as Data)
                return str
           // } catch {
           //     assertionFailure("Failed to transform `Data` to `NSArray` ")     return nil      }
        }
//---------------------------------------------------------------------------------------------------------------------
    func saveFile(fileName:String,flagType:Int)  {
        let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("photosFolder")

        if !FileManager.default.fileExists(atPath: path.absoluteString) {
        try! FileManager.default.createDirectory(at: path, withIntermediateDirectories: true, attributes: nil)
        }
        //let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
       // path.appendingPathComponent(fileName)
    }

    func addListImageGalery(image:UIImage,imageName:String, flagTypeGalery:Int ) {
        appDelegate = UIApplication.shared.delegate as? AppDelegate
        switch flagTypeGalery {
        case 0:
            listImageGalery.listElectricImageGalery.updateValue(image, forKey: listImageGalery.listElectricImageGalery.count)
            ////UserDefaults().set(imgNSData,forKey: "listNameElectricImageGalery_" + String(ind))
            //UserDefaults().set(listImageGalery.listNameElectricImageGalery, forKey: "listNameElectricImageGalery" )
            listImageGalery.listNameElectricImageGalery.updateValue(imageName, forKey: listImageGalery.listNameElectricImageGalery.count)
            save(imageData: image, name: imageName, flagWorker: 0)
           // var dictNSData:[Int:Data] = Dictionary()
           /* if appDelegate?.sim == 1 {
                var ind = 0
                for _ in listImageGalery.listElectricImageGalery {
                    let image = listImageGalery.listElectricImageGalery[ind]
                    do {
                        let imgNSData =  NSKeyedArchiver.archivedData(withRootObject :image)
                        dictNSData.updateValue(imgNSData,forKey:ind)
                        
                    }  catch  {
                            print("NSKeyedArchiver")
                        }
                    ind = ind + 1
                 }
                UserDefaults().set(dictNSData,forKey: "listElectricImageGalery")
            }
                */
        case 1:
            listImageGalery.listPlumberImageGalery.updateValue(image, forKey: listImageGalery.listPlumberImageGalery.count)
            listImageGalery.listNamePlumberImageGalery.updateValue(imageName, forKey: listImageGalery.listNamePlumberImageGalery.count)
            UserDefaults().set(listImageGalery.listNamePlumberImageGalery,forKey: "listNamePlumberImageGalery")
        case 2:
            listImageGalery.listHandymanImageGalery.updateValue(image, forKey: listImageGalery.listHandymanImageGalery.count)
            listImageGalery.listNameHandymanImageGalery.updateValue(imageName, forKey: listImageGalery.listNameHandymanImageGalery.count)
            UserDefaults().set(listImageGalery.listNameHandymanImageGalery,forKey: "listNameHandymanImageGalery")
        default:
            return
        }
        if appDelegate?.sim == 1 {
     //   self.save(imageData:image,name: imageName,flagWorker:flagTypeGalery)
        }
    }
    
    func setCoord(lat:Double,long:Double,flagOwnerCoord:Int) {
        switch flagOwnerCoord {
        case 0:
            place.coordHome.0 = lat
            place.coordHome.1 = long
        case 1:
            place.coordPlumberCur.0 = lat
            place.coordPlumberCur.1 = long
        case 2:
            place.coordElectricCur.0 = lat
            place.coordElectricCur.1 = long
        case 3:
            place.coordHandymanCur.0 = lat
            place.coordHandymanCur.1 = long
        default:
            return
        }
    }
    func setPlace(strPlace:String,flagOwnerCoord:Int) {
        switch flagOwnerCoord {
        case 0:
            place.placeHome = strPlace
          case 1:
            place.placeHomeElectric = strPlace
        case 2:
            place.placeHomePlumber = strPlace
        case 3:
            place.placeHomeHandyman = strPlace
        default:
            return
        }
    }
}
