import SwiftUI

struct LinkFormView: View {
    @EnvironmentObject var linkViewModel: LinkViewModel
    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) private var viewContext

    let link: Link?

    @State private var alias: String = ""
    @State private var originalURL: String = ""
    @State private var text: String = ""
    @State private var linkDescription: String = ""
    @State private var selectedLinkType: LinkType = .link
    @State private var selectedTags: [Tag] = []
    @State private var tagSearchText: String = ""
    @State private var isValidatingAlias: Bool = false
    @State private var aliasValidationMessage: String = ""
    @State private var urlValidationMessage: String = ""
    @State private var showingTagPicker: Bool = false
    @State private var saveErrorMessage: String = ""
    @State private var showingSaveError: Bool = false

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Tag.name, ascending: true)],
        animation: .default)
    private var allTags: FetchedResults<Tag>

    var isEditing: Bool {
        return link != nil
    }

    var filteredTags: [Tag] {
        if tagSearchText.isEmpty {
            return Array(allTags)
        } else {
            return allTags.filter { $0.name.localizedCaseInsensitiveContains(tagSearchText) }
        }
    }

    var canSave: Bool {
        return !alias.isEmpty &&
               (selectedLinkType == .custom ? !text.isEmpty : !originalURL.isEmpty) &&
               aliasValidationMessage.isEmpty &&
               urlValidationMessage.isEmpty
    }

    var templateValidationView: some View {
        Group {
            if selectedLinkType == .template && !originalURL.isEmpty {
                let isValidTemplate = URLTemplateProcessor.validateTemplate(originalURL)
                let hasParameters = URLTemplateProcessor.hasParameters(originalURL)

                if isValidTemplate && hasParameters {
                    // Valid template with parameters - show success with iOS blue
                    HStack {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundColor(.blue)
                        Text("Valid template with parameters")
                            .font(.caption)
                            .foregroundColor(.blue)
                    }
                } else if !hasParameters {
                    // No parameters detected - show warning
                    HStack {
                        Image(systemName: "exclamationmark.triangle.fill")
                            .foregroundColor(.orange)
                        Text("Template should contain parameters like {query} or {query,default=value}")
                            .font(.caption)
                            .foregroundColor(.orange)
                    }
                } else {
                    // Invalid template - show error
                    HStack {
                        Image(systemName: "xmark.circle.fill")
                            .foregroundColor(.red)
                        Text("Invalid template syntax. Use {parameter} or {parameter,default=value}")
                            .font(.caption)
                            .foregroundColor(.red)
                    }
                }
            }
        }
    }

    var body: some View {
        NavigationView {
            Form {
                Section("basic_information") {
                    // Alias field
                    VStack(alignment: .leading) {
                        TextField("alias", text: Binding(
                            get: { alias },
                            set: { newValue in
                                let lowered = newValue.lowercased()
                                let filtered = lowered.filter { ($0 >= "a" && $0 <= "z") || ($0 >= "0" && $0 <= "9") || $0 == "-" || $0 == "_" }
                                alias = filtered
                                validateAlias(filtered)
                            }
                        ))
                        .autocapitalization(.none)
                        .disableAutocorrection(true)
                        .onChange(of: alias) { newValue in
                            // Already validated in custom binding; ensure stored value is lowercase
                            if alias != alias.lowercased() {
                                alias = alias.lowercased()
                            }
                            }

                        if !aliasValidationMessage.isEmpty {
                            Text(aliasValidationMessage)
                                .font(.caption)
                                .foregroundColor(.red)
                        }
                    }

                    // Link Type Picker
                    Picker("link_type", selection: $selectedLinkType) {
                        ForEach(LinkType.allCases, id: \.self) { linkType in
                            Text(linkType.displayName).tag(linkType)
                        }
                    }
                    .pickerStyle(SegmentedPickerStyle())
                    .onChange(of: selectedLinkType) { _, newValue in
                        // Re-validate URL when link type changes
                        if newValue != .custom {
                            validateURL(originalURL)
                        } else {
                            urlValidationMessage = ""
                        }
                    }

                    // URL or Text field based on type
                    if selectedLinkType == .custom {
                        VStack(alignment: .leading) {
                            Text("markdown_content")
                                .font(.caption)
                                .foregroundColor(.secondary)
                            TextEditor(text: $text)
                                .frame(minHeight: 100)
                        }
                    } else {
                        VStack(alignment: .leading) {
                            TextField("original_url", text: $originalURL)
                                .autocapitalization(.none)
                                .autocorrectionDisabled()
                                .keyboardType(.URL)
                                .textFieldStyle(RoundedBorderTextFieldStyle())
                                .overlay(
                                    RoundedRectangle(cornerRadius: 8)
                                        .stroke(getBorderColor(), lineWidth: 2)
                                )
                                .onChange(of: originalURL) { _, newValue in
                                    validateURL(newValue)
                                }

                            if !urlValidationMessage.isEmpty {
                                HStack {
                                    Image(systemName: "exclamationmark.triangle")
                                        .foregroundColor(.orange)
                                    Text(urlValidationMessage)
                                        .font(.caption)
                                        .foregroundColor(.orange)
                                }
                            }

                            if selectedLinkType == .template {
                                VStack(alignment: .leading, spacing: 8) {
                                    // Template help text
                                    VStack(alignment: .leading, spacing: 4) {
                                        Text("Template type allows you to create dynamic URLs with parameters. Use {query, default=value} syntax in the URL.")
                                            .font(.caption)
                                            .foregroundColor(.secondary)

                                        Text("Example: https://google.com/search?q={query, default=hello}")
                                            .font(.caption)
                                            .foregroundColor(.secondary)
                                            .padding(.horizontal, 8)
                                            .padding(.vertical, 4)
                                            .background(Color.gray.opacity(0.1))
                                            .cornerRadius(4)
                                    }

                                    // Template validation status
                                    if !originalURL.isEmpty {
                                        templateValidationView
                                    }
                                }
                            }
                        }
                    }

                    // Description field
                    TextField("description_optional", text: $linkDescription)
                }

                Section("tags") {
                    // Selected tags
                    if !selectedTags.isEmpty {
                        ScrollView(.horizontal, showsIndicators: false) {
                            HStack {
                                ForEach(selectedTags, id: \.id) { tag in
                                    TagChip(tag: tag, onRemove: {
                                        selectedTags.removeAll { $0.id == tag.id }
                                    })
                                }
                            }
                            .padding(.horizontal)
                        }
                    }

                    // Tag search and selection
                    HStack {
                        TextField("search_or_create_tag", text: $tagSearchText)

                        Button("add") {
                            addOrCreateTag()
                        }
                        .disabled(tagSearchText.isEmpty)
                    }

                    // Filtered tags list
                    ForEach(filteredTags.prefix(5), id: \.id) { tag in
                        HStack {
                            Text(tag.name)
                            Spacer()
                            if selectedTags.contains(where: { $0.id == tag.id }) {
                                Image(systemName: "checkmark")
                                    .foregroundColor(.blue)
                            }
                        }
                        .onTapGesture {
                            toggleTag(tag)
                        }
                    }
                }

                if isEditing {
                    Section("actions") {
                        Button("delete_link", role: .destructive) {
                            if let link = link {
                                linkViewModel.deleteLink(link)
                                presentationMode.wrappedValue.dismiss()
                            }
                        }
                    }
                }
            }
            .navigationTitle(isEditing ? "edit_link" : "add_link")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("cancel") {
                        presentationMode.wrappedValue.dismiss()
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("save") {
                        saveLink()
                    }
                    .disabled(!canSave)
                }
            }
        }
        .onAppear {
            setupForm()
        }
        .alert("Error", isPresented: $showingSaveError) {
            Button("OK") {
                showingSaveError = false
                saveErrorMessage = ""
            }
        } message: {
            Text(saveErrorMessage)
        }
    }

    private func setupForm() {
        if let link = link {
            alias = link.alias
            originalURL = link.originalURL ?? ""
            text = link.text ?? ""
            linkDescription = link.linkDescription ?? ""
            selectedLinkType = link.linkTypeEnum
            selectedTags = link.sortedTags

            // Validate existing data
            validateAlias(alias)
            validateURL(originalURL)
        }
    }

    private func validateAlias(_ newAlias: String) {
        isValidatingAlias = true

        // Basic validation
        if newAlias.isEmpty {
            aliasValidationMessage = ""
            isValidatingAlias = false
            return
        }

        // Check format (alphanumeric and some special characters)
        let allowedCharacters = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-_"))
        if newAlias.unicodeScalars.contains(where: { !allowedCharacters.contains($0) }) {
            aliasValidationMessage = NSLocalizedString("alias_invalid_characters", comment: "Alias contains invalid characters")
            isValidatingAlias = false
            return
        }

        // Check if alias exists (excluding current link if editing)
        if !isEditing || (isEditing && newAlias != link?.alias) {
            if linkViewModel.aliasExists(newAlias) {
                aliasValidationMessage = NSLocalizedString("alias_already_exists", comment: "Alias already exists")
            } else {
                aliasValidationMessage = ""
            }
        } else {
            aliasValidationMessage = ""
        }

        isValidatingAlias = false
    }

    private func validateURL(_ url: String) {
        // Don't validate empty URLs (allow empty for templates with placeholders)
        if url.isEmpty {
            urlValidationMessage = ""
            return
        }

        // For templates, use URLTemplateProcessor for validation
        if selectedLinkType == .template {
            // Check if it's a valid template
            if URLTemplateProcessor.validateTemplate(url) {
                // Check if the base URL (without parameters) is valid
                let urlWithoutPlaceholders = url.replacingOccurrences(of: #"\{[^}]+\}"#, with: "placeholder", options: .regularExpression)
                if isValidURL(urlWithoutPlaceholders) {
                    urlValidationMessage = ""
                    return
                } else {
                    urlValidationMessage = NSLocalizedString("invalid_base_url_format", comment: "Invalid base URL format")
                    return
                }
            } else {
                urlValidationMessage = NSLocalizedString("invalid_template_format", comment: "Invalid template format")
                return
            }
        }

        // For regular links, validate the URL strictly
        if selectedLinkType == .link {
            if isValidURL(url) {
                urlValidationMessage = ""
                return
            }
        }

        // If we reach here, the URL is invalid
        urlValidationMessage = NSLocalizedString("invalid_url_format", comment: "Invalid URL format")
    }

    private func isValidURL(_ urlString: String) -> Bool {
        // First check if it's a valid URL
        guard let url = URL(string: urlString) else {
            return false
        }

        // Check if it has a scheme
        guard let scheme = url.scheme else {
            return false
        }

        // Allow http, https, and other common schemes
        let allowedSchemes = ["http", "https", "ftp", "mailto", "tel", "sms"]
        if !allowedSchemes.contains(scheme.lowercased()) {
            return false
        }

        // Check if it has a host for http/https URLs
        if ["http", "https"].contains(scheme.lowercased()) {
            guard let host = url.host, !host.isEmpty else {
                return false
            }
        }

        return true
    }

    private func getBorderColor() -> Color {
        // Show error state if there's a validation message
        if !urlValidationMessage.isEmpty {
            return .orange
        }

        // For template links, show blue if valid template with parameters
        if selectedLinkType == .template && !originalURL.isEmpty {
            let isValidTemplate = URLTemplateProcessor.validateTemplate(originalURL)
            let hasParameters = URLTemplateProcessor.hasParameters(originalURL)

            if isValidTemplate && hasParameters {
                return .blue
            }
        }

        return .clear
    }

    private func toggleTag(_ tag: Tag) {
        if selectedTags.contains(where: { $0.id == tag.id }) {
            selectedTags.removeAll { $0.id == tag.id }
        } else {
            selectedTags.append(tag)
        }
    }

    private func addOrCreateTag() {
        let trimmedText = tagSearchText.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmedText.isEmpty else { return }

        // Check if tag already exists
        if let existingTag = allTags.first(where: { $0.name.lowercased() == trimmedText.lowercased() }) {
            if !selectedTags.contains(where: { $0.id == existingTag.id }) {
                selectedTags.append(existingTag)
            }
        } else {
            // Create new tag
            let newTag = Tag(context: viewContext)
            newTag.name = trimmedText
            newTag.slug = trimmedText.lowercased().replacingOccurrences(of: " ", with: "-")
            newTag.createdAt = Date()

            do {
                try viewContext.save()
                selectedTags.append(newTag)
            } catch {
                print("Error creating tag: \(error)")
            }
        }

        tagSearchText = ""
    }

    private func saveLink() {
        // Clear any previous error
        saveErrorMessage = ""
        showingSaveError = false

        // Validate before saving
        if !aliasValidationMessage.isEmpty {
            saveErrorMessage = aliasValidationMessage
            showingSaveError = true
            return
        }

        if !urlValidationMessage.isEmpty && selectedLinkType != .custom {
            saveErrorMessage = urlValidationMessage
            showingSaveError = true
            return
        }

        let success: Bool

        if isEditing, let link = link {
            success = linkViewModel.updateLink(
                link,
                alias: alias,
                originalURL: selectedLinkType == .custom ? nil : originalURL,
                text: selectedLinkType == .custom ? text : nil,
                linkType: selectedLinkType,
                description: linkDescription.isEmpty ? nil : linkDescription,
                tags: selectedTags
            )
        } else {
            success = linkViewModel.createLink(
                alias: alias,
                originalURL: selectedLinkType == .custom ? nil : originalURL,
                text: selectedLinkType == .custom ? text : nil,
                linkType: selectedLinkType,
                description: linkDescription.isEmpty ? nil : linkDescription,
                tags: selectedTags
            )
        }

        if success {
            presentationMode.wrappedValue.dismiss()
        } else {
            // Show error from view model
            if let errorMessage = linkViewModel.errorMessage {
                saveErrorMessage = errorMessage
                showingSaveError = true
                linkViewModel.errorMessage = nil // Clear the error
            }
        }
    }
}

struct TagChip: View {
    let tag: Tag
    let onRemove: () -> Void

    var body: some View {
        HStack(spacing: 4) {
            Text(tag.name)
                .font(.caption)

            Button(action: onRemove) {
                Image(systemName: "xmark")
                    .font(.caption2)
            }
        }
        .padding(.horizontal, 8)
        .padding(.vertical, 4)
        .background(Color.blue.opacity(0.2))
        .foregroundColor(.blue)
        .cornerRadius(6)
    }
}

#Preview {
    LinkFormView(link: nil)
        .environmentObject(LinkViewModel())
        .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
