//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import SwiftUI
import UIKit

/// Issue report screen in developer menu
@available(iOS 13.0, *)
struct IssueReporter: View {
    @State var issueDescription: String = ""
    @State var includeLogs = true
    @State var includeEnvInfo = true
    @State var includeDeviceInfo = true
    @State var showAlertIfInvalidURL = false

    private static let minCharacterLimit = 140
    private let issueDescriptionHint = "Please provide a short description of the issue.."
    private let includeLogsText = "Include logs"
    private let includeEnvInfoText = "Include environment information"
    private let includeDeviceInfoText = "Include device information"
    private let reportOnGithubButtonText = "Report on Github"
    private let copyToClipboardButtonText = "Copy to Clipboard"
    private let screenTitle = "Report Issue"
    private let amplifyIosNewIssueUrl = "https://github.com/aws-amplify/amplify-ios/issues/new?&title=&body="
    private let githubURLErrorTitle = "Error"
    private let githubURLErrorMessage = "Unable to parse Github URL. Please use the Copy to Clipboard option."
    private let moreCharactersRequired = "Characters required"

    var body: some View {
        ScrollView {
            VStack {
                MultilineTextField(text: $issueDescription, placeHolderText: issueDescriptionHint)
                    .border(Color.gray)
                    .frame(height: 350)

                HStack {
                    Text("\(moreCharactersRequired): \(remainingCharactersRequired())")
                        .foregroundColor(Color.secondary)
                        .font(.system(size: 15))
                    Spacer()
                }.padding(.bottom)

                Toggle(isOn: $includeEnvInfo) {
                    Text(includeEnvInfoText).bold()
                }.padding(.bottom)

                Toggle(isOn: $includeDeviceInfo) {
                    Text(includeDeviceInfoText).bold()
                }.padding(.bottom)

                Spacer()

                Button(reportOnGithubButtonText, action: reportToGithub)
                    .padding()
                    .font(.subheadline)
                    .frame(maxWidth: .infinity)
                    .border(Color.blue)
                    .padding(.bottom)
                    .alert(isPresented: $showAlertIfInvalidURL) {
                        Alert(title: Text(githubURLErrorTitle),
                              message: Text(githubURLErrorMessage),
                              dismissButton: .default(Text("OK")))
                    }
                    .disabled(shouldDisableReporting())

                Button(copyToClipboardButtonText, action: copyToClipboard)
                    .padding()
                    .font(.subheadline)
                    .frame(maxWidth: .infinity)
                    .border(Color.blue)
                    .disabled(shouldDisableReporting())

            }.padding()
                .navigationBarTitle(Text(screenTitle))
        }
    }

    /// Get number of extra characters required for a valid issue description length
    /// Returns 0 if issue description length fulfills `minCharacterLimit` criteria
    private func remainingCharactersRequired() -> Int {
        return max(IssueReporter.minCharacterLimit - issueDescription.count, 0)
    }

    private func shouldDisableReporting() -> Bool {
      return remainingCharactersRequired() > 0
    }

    /// Open Amplify iOS issue logging screen on Github
    private func reportToGithub() {
        let issueDescriptionMarkdown =
            IssueInfoHelper.generateMarkdownForIssue(
                issue: IssueInfo(issueDescription: issueDescription,
                         includeEnvInfo: includeEnvInfo,
                         includeDeviceInfo: includeDeviceInfo))

        let urlString = amplifyIosNewIssueUrl + issueDescriptionMarkdown
        guard let url = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
            showAlertIfInvalidURL = true
            return
        }
        guard let urlToOpen = URL(string: url) else {
            showAlertIfInvalidURL = true
            return
        }

//        UIApplication.shared.open(urlToOpen)
    }

    /// Copy issue as a markdown string to clipboard
    private func copyToClipboard() {
        UIPasteboard.general.string =
            IssueInfoHelper.generateMarkdownForIssue(
                issue: IssueInfo(issueDescription: issueDescription,
                                 includeEnvInfo: includeEnvInfo,
                                 includeDeviceInfo: includeDeviceInfo)
            )
    }
}

@available(iOS 13.0.0, *)
final class IssueReporter_Previews: PreviewProvider {
    static var previews: some View {
        IssueReporter()
    }
}

/// Custom defined view for multi line text field
@available(iOS 13.0, *)
final class MultilineTextField: UIViewRepresentable {
    @Binding var text: String
    var placeHolderText: String = ""

    init(text: Binding<String>, placeHolderText: String) {
        self._text = text
        self.placeHolderText = placeHolderText
    }

    func makeUIView(context: UIViewRepresentableContext<MultilineTextField>) -> UITextView {
        let view = UITextView()
        view.isScrollEnabled = true
        view.isEditable = true
        view.isUserInteractionEnabled = true
        view.delegate = context.coordinator
        view.font = .systemFont(ofSize: 15)
        view.textColor = .secondaryLabel
        view.text = placeHolderText

        /// add a dismiss button in UIToolbar for keyboard
        let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 35))
        let emptySpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let dismissButton = UIBarButtonItem(title: "Dismiss", style: .done,
                                            target: self, action: #selector(dismissKeyboard))
        toolbar.setItems([emptySpace, dismissButton], animated: false)
        toolbar.sizeToFit()

        view.inputAccessoryView = toolbar
        return view
    }

    @objc func dismissKeyboard() {
//        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder),
//                                        to: nil, from: nil, for: nil)
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
    }

    func makeCoordinator() -> Coordinator {
        return MultilineTextField.Coordinator(parent: self)
    }

    class Coordinator: NSObject, UITextViewDelegate {
        var parent: MultilineTextField

        init(parent: MultilineTextField) {
            self.parent = parent
        }

        func textViewDidChange(_ textView: UITextView) {
            parent.text = textView.text
        }

        func textViewDidBeginEditing(_ textView: UITextView) {
            if textView.textColor == .secondaryLabel {
                textView.text = nil
                textView.textColor = .label
            }
        }
    }
}
