//
//  PostRecipeViewController.swift
//  kikurageApp
//
//  Created by Shusuke Ota on 2020/12/28.
//  Copyright © 2020 shusuke. All rights reserved.
//

import UIKit
import PKHUD

class PostRecipeViewController: UIViewController, UIViewControllerNavigatable {
    private var baseView: PostRecipeBaseView { self.view as! PostRecipeBaseView } // swiftlint:disable:this force_cast
    private var viewModel: PostRecipeViewModel!
    private var cameraCollectionViewModel: CameraCollectionViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()
        cameraCollectionViewModel = CameraCollectionViewModel(selectedImageMaxNumber: Constants.CameraCollectionCell.maxNumber)
        viewModel = PostRecipeViewModel(recipeRepository: RecipeRepository())
        setDelegateDataSource()
    }
}
// MARK: - Initialized
extension PostRecipeViewController {
    private func setDelegateDataSource() {
        baseView.delegate = self
        baseView.recipeNameTextField.delegate = self
        baseView.dateTextField.delegate = self
        baseView.recipeMemoTextView.delegate = self
        baseView.cameraCollectionView.delegate = self
        baseView.cameraCollectionView.dataSource = cameraCollectionViewModel
        cameraCollectionViewModel.cameraCellDelegate = self
        viewModel.delegate = self
    }
}
// MARK: - BaseView Delegate
extension PostRecipeViewController: PostRecipeBaseViewDelegate {
    func didTapPostButton() {
        UIAlertController.showAlert(style: .alert, viewController: self, title: "こちらの投稿内容で\n良いですか", message: nil, okButtonTitle: "OK", cancelButtonTitle: "キャンセル") {
            HUD.show(.progress)
            if let kikurageUserId = LoginHelper.shared.kikurageUserId {
                self.viewModel.postRecipe(kikurageUserId: kikurageUserId)
            }
        }
    }
    func didTapCloseButton() {
        presentingViewController?.dismiss(animated: true, completion: nil)
    }
}
// MARK: - UITextField Delegate
extension PostRecipeViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField == baseView.recipeNameTextField {
            if let text = textField.text {
                let resultText = (text as NSString).replacingCharacters(in: range, with: string)
                return resultText.count <= baseView.maxRecipeNameNumer
            }
        }
        return true
    }
    func textFieldDidChangeSelection(_ textField: UITextField) {
        guard let text = textField.text else { return }
        baseView.setCurrentRecipeNameNumber(text: text)
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        switch textField {
        case baseView.dateTextField:
            setRecipeDateTextFieldData()
        case baseView.recipeNameTextField:
            setRecipeNameTextFieldData()
        default:
            break
        }
    }
    private func setRecipeDateTextFieldData() {
        let dateString = DateHelper.formatToString(date: baseView.datePicker.date)
        baseView.dateTextField.text = dateString
        viewModel.recipe.cookDate = dateString
    }
    private func setRecipeNameTextFieldData() {
        guard let recipeName = baseView.recipeNameTextField.text else { return }
        viewModel.recipe.name = recipeName
    }
}
// MARK: - UITextView Delegate
extension PostRecipeViewController: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        var resultText = ""
        if let text = textView.text {
            resultText = (text as NSString).replacingCharacters(in: range, with: text)
        }
        return resultText.count <= baseView.maxRecipeMemoNumber
    }
    func textViewDidChange(_ textView: UITextView) {
        guard let text = textView.text else { return }
        baseView.recipeMemoTextView.switchPlaceholderDisplay(text: text)
        viewModel.recipe.memo = text
        baseView.setCurrentRecipeMemoNumber(text: text)
    }
}
// MARK: - CameraCell Delegate
extension PostRecipeViewController: CameraCellDelegate {
    func didTapImageCancelButton(cell: CameraCell) {
        let index = cell.tag
        cameraCollectionViewModel.cancelImage(index: index)
        baseView.cameraCollectionView.reloadItems(at: [IndexPath(row: index, section: 0)])
    }
}
// MARK: - UICollectionView Delegate
extension PostRecipeViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        openImagePicker()
    }
}
// MARK: - UIImagePickerController Delegage
extension PostRecipeViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        guard let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
        guard let selectedIndexPath = baseView.cameraCollectionView.indexPathsForSelectedItems?.first else { return }
        picker.dismiss(animated: true) { [weak self] in
            self?.cameraCollectionViewModel.setImage(selectedImage: originalImage, index: selectedIndexPath.item)
            self?.baseView.cameraCollectionView.reloadItems(at: [selectedIndexPath])
        }
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}
// MARK: - PostRecipeViewModel Delegate
extension PostRecipeViewController: PostRecipeViewModelDelegate {
    func didSuccessPostRecipe() {
        // nil要素を取り除き、選択した画像のみData型に変換する
        let postIamgeData: [Data?] = cameraCollectionViewModel.changeToImageData(compressionQuality: 0.5).filter { $0 != nil }
        // Firestoreにデータ登録後、そのdocumentIDをパスに使ってStorageへ画像を投稿する
        if let kikurageUserId = LoginHelper.shared.kikurageUserId {
            viewModel.postRecipeImages(kikurageUserId: kikurageUserId, imageData: postIamgeData)
        }
    }
    func didFailedPostRecipe(errorMessage: String) {
        print(errorMessage)
        HUD.hide()
        UIAlertController.showAlert(style: .alert, viewController: self, title: "料理記録の登録に失敗しました", message: nil, okButtonTitle: "OK", cancelButtonTitle: nil, completionOk: nil)
    }
    func didSuccessPostRecipeImages() {
        HUD.hide()
        UIAlertController.showAlert(style: .alert, viewController: self, title: "栽培記録を保存しました", message: nil, okButtonTitle: "OK", cancelButtonTitle: nil) {
            // 料理記録一覧画面へ更新イベントを通知
            NotificationCenter.default.post(name: .updatedRecipes, object: nil)
            self.dismiss(animated: true, completion: nil)
        }
    }
    func didFailedPostRecipeImages(errorMessage: String) {
        print(errorMessage)
        HUD.hide()
        UIAlertController.showAlert(style: .alert, viewController: self, title: "料理記録の登録に失敗しました", message: nil, okButtonTitle: "OK", cancelButtonTitle: nil, completionOk: nil)
    }
}
