//
//  ListOffersCell.swift
//  NearbyStores
//
//  Created by Amine on 5/30/18.
//  Copyright © 2018 Amine. All rights reserved.
//

import UIKit
import SwiftEventBus
import AssistantKit
import CoreLocation

class ListOfferView: BaseView, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, OfferLoaderDelegate, EmptyLayoutDelegate, ErrorLayoutDelegate, FilterViewListDelegate {

 

    //request
    var __req_category: Int = 0
    var __req_redius: Int = AppConfig.distanceMaxValue
    var __req_search: String = ""
    var __req_page: Int = 1
    var __req_store: Int = 0
    var __req_date: String = ""


    var __req_lat: Double?
    var __req_lng: Double?

    //RESULT
    var GLOBAL_COUNT: Int = 0
    var LIST: [Offer] = [Offer]()
    
    
    var extra_parameters: [String: String] = [:]
    

    //Declare User For Current Session
    var myUserSession: User? = nil


    //Cell ID for collection
    var cellId = "offerCellId"


    //instance for scrolling
  
    lazy var collectionView: UICollectionView = {

        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        cv.backgroundColor = Colors.bg_gray_100


        if let flowLayout = cv.collectionViewLayout as? UICollectionViewFlowLayout {
            flowLayout.minimumLineSpacing = 0
        }

        cv.dataSource = self
        cv.delegate = self
        return cv

    }()


    var viewManager: LoaderViewManager = LoaderViewManager()


    override func setupViews() {
        

        if #available(iOS 10.0, *) {
            collectionView.refreshControl = refreshControl
        } else {
            collectionView.addSubview(refreshControl)
        }

        // Configure Refresh Control
        refreshControl.addTarget(self, action: #selector(refreshData(_:)), for: .valueChanged)


//        let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
//        layout.minimumInteritemSpacing = 10
//        layout.minimumLineSpacing = 10
//        collectionView.collectionViewLayout = layout
//

        __req_date = DateUtils.getCurrent(format: DateUtils.defaultFormatUTC)
    }

    private let refreshControl = UIRefreshControl()


    override func fetch(request: String) {


        if let session = Session.getInstance(), let user = session.user {
            myUserSession = user
        }

        isFetched = true

        Utils.printDebug("Fetch ListOffers")

        addSubview(collectionView)
        addConstraintsWithFormat(format: "H:|[v0]|", views: collectionView)
        addConstraintsWithFormat(format: "V:|[v0]|", views: collectionView)

        collectionView.register(UINib(nibName: "OfferCell", bundle: nil), forCellWithReuseIdentifier: cellId)

      
        load()


        //get params
        SwiftEventBus.onMainThread(self, name: "on_search_offers") { result in

            if let object = result?.object {

                let array: [String: String] = object as! [String: String]

                self.__req_lat = nil
                self.__req_lng = nil
                
                self.__req_redius = Int(array["radius"]!)!
                self.__req_search = array["search"]!
                self.__req_page = 1

                if let cat = array["category"] {
                    self.__req_category = Int(cat)!
                }

                if let lat = array["req_lat"] {
                    self.__req_lat = Double(lat)!
                }

                if let lng = array["req_lng"] {
                    self.__req_lng = Double(lng)!
                }

                self.viewManager.showAsLoading()
                self.load()


            }

        }


        //setup view loader, Error, Empty layouts
        viewManager.setup(parent: self)
        viewManager.getEmptyLayout().delegate = self
        viewManager.getErrorLayout().delegate = self


    }


    @objc private func refreshData(_ sender: Any) {
        //Init params
        __req_page = 1
        __req_page = 1
        __req_lat = nil
        __req_lng = nil
        __req_category = 0
        __req_search = ""

        // Fetch Data
        load()
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
                    -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! OfferCell

        cell.setupSettings()
        cell.setup(object: LIST[indexPath.item])


        return cell
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        let offer = self.LIST[indexPath.row]
        offer.save()

        if let controller = self.viewController {

            let sb = UIStoryboard(name: "OfferDetail", bundle: nil)
            if sb.instantiateInitialViewController() != nil {

                let ms: OfferDetailViewController = sb.instantiateViewController(withIdentifier: "offerdetailVC") as! OfferDetailViewController

                ms.offer_id = offer.id

                controller.present(ms, animated: true)
            }
        }

    }


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return LIST.count
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {

       
        guard let filter = mFilterViewList else {
            return
        }
        
        Utils.printDebug("\(scrollView.contentOffset.y) -  \(filter.frame.height)")
               
        
            if scrollView.contentOffset.y > filter.frame.height {
                UIView.animate(withDuration: 0.3) {
                    filter.alpha = 0
                }
            }else{
                UIView.animate(withDuration: 0.3) {
                    filter.alpha = 1
                }
            }
       
        
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {


        if Device.isPhone {
            let finalHeight = frame.width / 2.0
            let finalWidth = frame.width - 20
            return CGSize(width: finalWidth, height: finalHeight)
        } else if Device.isPad {
            let finalHeight = (frame.width / 3.5)
            let finalWidth = (frame.width / 2) - 11
            return CGSize(width: finalWidth, height: finalHeight)
        } else {
            let finalHeight = frame.width / 2.0
            let finalWidth = frame.width - 20
            return CGSize(width: finalWidth, height: finalHeight)
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

        if Device.isPad {

            if Device.screen == .inches_9_7 {
                return UIEdgeInsets(top: 10, left: 6, bottom: 0, right: 6)
            } else {
                return UIEdgeInsets(top: 20, left: 6, bottom: 0, right: 6)
            }

        } else {
            return UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
        }
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {

        //item = 10, count = 10 , COUNT = 23

        Utils.printDebug(" Paginate \((indexPath.item + 1)) - \(LIST.count) - \(GLOBAL_COUNT)")

        if indexPath.item + 1 == LIST.count && LIST.count < GLOBAL_COUNT && !isLoading {
            Utils.printDebug(" Paginate! \(__req_page) ")
            self.load()
        }

    }

    private var isLoading = false


    //API

    var offerLoader: OfferLoader = OfferLoader()

    func load() {

        if __req_page == 1 {
            make_as_loader()
        } else {
            self.viewManager.showAsLoading()
        }


        self.offerLoader.delegate = self

        //Get current Location

        var parameters = [
            "limit": "10"
        ]

        if let lat = __req_lat, let lng = __req_lng {

            parameters["latitude"] = String(describing: lat)
            parameters["longitude"] = String(describing: lng)

        } else if let guest = Guest.getInstance() {

            parameters["latitude"] = String(guest.lat)
            parameters["longitude"] = String(guest.lng)

        }


        if __req_redius > 0 && __req_redius < 100 {
            parameters["radius"] = String((__req_redius * 1000)) //radius by merters
        }

        parameters["category_id"] = String(__req_category)
        parameters["page"] = String(__req_page)
        parameters["search"] = String(__req_search)

        parameters["store_id"] = String(__req_store)


        parameters["date"] = String(__req_date)
        parameters["timezone"] = String(TimeZone.current.identifier)
        
        parameters["order_by"] = self.__req_order_by
        
        for (k, v) in extra_parameters{
            parameters[k] = v
        }
        
        if let order = extra_parameters["__req_order"]{
            parameters["order_by"] = order
        }

        Utils.printDebug("\(parameters)")
        

        self.isLoading = true
        self.offerLoader.load(url: Constances.Api.API_GET_OFFERS, parameters: parameters)


    }


    func success(parser: OfferParser, response: String) {


        if(self.__req_page == 1){
             self.make_as_result()
        }
        
        
        self.viewManager.showMain()
        self.refreshControl.endRefreshing()

        if parser.success == 1 {


            let offers = parser.parse()


            self.GLOBAL_COUNT = parser.count

            if offers.count > 0 {

                Utils.printDebug("We loaded \(offers.count)")


                if self.__req_page == 1 {
                    self.LIST = offers
                } else {
                    self.LIST += offers
                }

                self.collectionView.reloadData()

                if self.LIST.count < self.GLOBAL_COUNT {
                    self.__req_page += 1
                }


            } else {

                if self.LIST.count == 0 {

                    emptyAndReload()
                    //show emty layout
                    viewManager.showAsEmpty()

                } else if self.__req_page == 1 {

                    emptyAndReload()

                    viewManager.showAsEmpty()

                    Utils.printDebug("===> Is Empty!")
                }


            }

        } else {

            if let errors = parser.errors {

                Utils.printDebug("===> Request Error with Messages! ListOffers")
                Utils.printDebug("\(errors)")

                viewManager.showAsError()

            }

        }
        
        
        self.isLoading = false

    }

    func emptyAndReload() {

        self.LIST = []
        self.GLOBAL_COUNT = 0
        self.collectionView.reloadData()

    }

    func error(error: Error?, response: String) {

        self.isLoading = false
        self.refreshControl.endRefreshing()
        self.viewManager.showAsError()

        Utils.printDebug("===> Request Error! ListOffers")
        Utils.printDebug("\(response)")

    }


    func onReloadAction(action: ErrorLayout) {

        self.viewManager.showAsLoading()

        __req_search = ""
        __req_page = 1
        __req_page = 1
        __req_lat = nil
        __req_lng = nil
        __req_category = 0
        __req_search = ""

        load()

    }

    func onReloadAction(action: EmptyLayout) {

        self.viewManager.showAsLoading()

        __req_search = ""
        __req_page = 1
        __req_page = 1
        __req_lat = nil
        __req_lng = nil
        __req_category = 0
        __req_search = ""

        load()

    }
    
    
    var mFilterViewList: FilterViewList? = nil
    
    func setupFilterView() {
           
           let padding = UIEdgeInsets(top: 40, left: 0, bottom: 0, right: 0)
           collectionView.contentInset = padding
           
           
           mFilterViewList = UINib(nibName: "FilterViewList", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! FilterViewList
           
        addSubview(mFilterViewList!)
           
        mFilterViewList!.translatesAutoresizingMaskIntoConstraints = false
           
           // lets set up some constraints for our label
           let constraints = [
               
            mFilterViewList!.topAnchor.constraint(equalTo: topAnchor, constant: 1),
            mFilterViewList!.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1),
            mFilterViewList!.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 1),
            mFilterViewList!.heightAnchor.constraint(equalToConstant: 40)
               
           ]
           
           
           NSLayoutConstraint.activate(constraints)
           
        mFilterViewList!.delegate = self
        mFilterViewList!.initViews()
           
           
           self.__req_order_by = "recent"
           
       }
       
       var __req_order_by = ""
       
       
       func onJobListFilterDatePressed() {
           self.__req_order_by = "recent"
           self.__req_page = 1
           self.LIST = []
           self.collectionView.reloadData()
           load()
       }
       
       func onJobListFilterDistancePressed() {
           
           
           if CLLocationManager.locationServicesEnabled() {
                switch CLLocationManager.authorizationStatus() {
                   case .notDetermined, .restricted, .denied:
                       print("No access")
                       SwiftEventBus.post("update_location", sender: true)
                   case .authorizedAlways, .authorizedWhenInUse:
                       print("Access")
                   }
               } else {
                    SwiftEventBus.post("update_location", sender: true)
                   print("Location services are not enabled")
           }
           
           
           self.__req_order_by = ""
           self.__req_page = 1
           self.LIST = []
           self.collectionView.reloadData()
           load()
           
       }

    
 
    
      

}


extension ListOfferView{
    
    func make_as_loader(){
        
        self.LIST = []
        
        let object = Offer()
        for _ in 0...5{
            self.LIST.append(object)
        }
        
        self.collectionView.reloadData()
        self.collectionView.isScrollEnabled = false
        
    }
    
    func make_as_result() {
        
        self.LIST = []
        self.collectionView.reloadData()
        self.collectionView.isScrollEnabled = true
    }
    
}


extension ListOfferView{
    
    enum Request {
        static let nearby = "nearby"
        static let featured = "featured"
        static let recent = "recent"
        static let saved = "saved"
        static let own = "own"
        static let top_rated = "top_rated"
        static let nearby_top_rated = "nearby_top_rated"
    }
}
