//
//  SQRadio.swift
//  Sequoia
//
//  Created by Victor on 10/10/2024.
//

import SwiftUI

enum SQRadioOrientation {
    case horizontal
    case vertical
}

struct SQRadioOption: Identifiable {
    let id: Int = UUID().hashValue
    let title: String
    var desc: String? = nil

    init(title: String, desc: String? = nil) {
        self.title = title
        self.desc = desc
    }
}

struct SQRadio: View {
    let title: String?
    let titleSize: CGFloat
    var radioTextSize: CGFloat = 16
    var orientation: SQRadioOrientation = .vertical
    let options: [SQRadioOption]
    var error: Binding<SQFormFieldError>
    @Binding var selectedIndex: Int?

    init(title: String? = nil, titleSize: CGFloat = 24, radioTextSize: CGFloat = 16, orientation: SQRadioOrientation = .vertical, options: [SQRadioOption], selectedIndex: Binding<Int?>, error: Binding<SQFormFieldError> = .constant(.none)) {
        self.title = title
        self.titleSize = titleSize
        self.radioTextSize = radioTextSize
        self.orientation = orientation
        self.options = options
        self.error = error
        self._selectedIndex = selectedIndex
    }

    var body: some View {
        VStack(alignment: orientation == .vertical ? .leading : .center, spacing: 16) {
            if let title = title {
                SQText(title)
                    .sqSize(titleSize)
                    .sqFont(.bold)
                    .multilineTextAlignment(.center)
            }
            Group {
                if orientation == .horizontal {
                    HorizontalRadioButtons(options: options, titleSize: radioTextSize, selectedIndex: $selectedIndex, isInError: error.wrappedValue.isInError)
                        .frame(maxWidth: .infinity)

                } else {
                    VStack(alignment: .leading, spacing: 16) {
                        radioButtons
                    }
                }
            }

            if error.wrappedValue != .none {
                SQText(error.wrappedValue.message)
                    .sqSize(12)
                    .sqFont(.semiBold)
                    .sqColor(.sqSemanticRed)
            }
        }
    }

    private var radioButtons: some View {
        ForEach(Array(options.enumerated()), id: \.offset) { index, option in
            RadioButton(
                title: option.title,
                desc: option.desc,
                titleSize: radioTextSize,
                isSelected: Binding(
                    get: { selectedIndex == index },
                    set: { _ in selectedIndex = index }
                ),
                isInError: error.wrappedValue.isInError,
                orientation: orientation
            )
        }
    }

    private struct HorizontalRadioButtons: View {
        let options: [SQRadioOption]
        let titleSize: CGFloat
        @Binding var selectedIndex: Int?
        var isInError: Bool

        var body: some View {
            GeometryReader { geometry in
                HStack(alignment: .top, spacing: 0) {
                    Spacer()
                    ForEach(Array(options.enumerated()), id: \.offset) { index, option in
                        RadioButton(
                            title: option.title,
                            desc: option.desc,
                            titleSize: titleSize,
                            isSelected: Binding(
                                get: { selectedIndex == index },
                                set: { _ in selectedIndex = index }
                            ),
                            isInError: isInError,
                            orientation: .horizontal
                        )
                        .frame(width: geometry.size.width / CGFloat(options.count))
                    }
                    Spacer()
                }
            }
            .frame(height: 80)
        }
    }

    private struct RadioButton: View {
        let title: String
        let desc: String?
        let titleSize: CGFloat
        @Binding var isSelected: Bool
        var isInError: Bool
        let orientation: SQRadioOrientation

        var body: some View {
            Group {
                if orientation == .horizontal {
                    VStack(spacing: 8) {
                        radioCircle
                        SQText(title)
                            .multilineTextAlignment(.center)
                    }
                } else {
                    VStack(alignment: .leading) {
                        HStack(spacing: 8) {
                            radioCircle
                            SQText(title)
                        }

                        if let desc = desc {
                            SQText(desc)
                                .sqSize(12)
                        }
                    }
                }
            }
            .contentShape(Rectangle())  // Make the entire area tappable
            .onTapGesture {
                isSelected.toggle()
            }
        }

        private var radioCircle: some View {
            ZStack {
                Circle()
                    .stroke(isInError ? Color.sqSemanticRed :
                        (isSelected ?
                        Color.sqNeutral(100) :
                            Color.sqNeutral(30)), lineWidth: 1)
                    .frame(width: 20, height: 20)

                if isSelected {
                    Circle()
                        .inset(by: 3)
                        .stroke(isInError ? Color.sqSemanticRed : Color.sqNeutral(100), lineWidth: 6)
                        .frame(width: 20, height: 20)
                }
            }
        }
    }
}

#Preview {
    VStack(alignment: .leading, spacing: 32) {
        SQRadio(title: "Vertical", options: [
            SQRadioOption(title: "Option 1", desc: "L’utilisateur semble proposer un service relevant d’une activité réglementée sans disposer des autorisations requises."),
            SQRadioOption(title: "Option 2", desc: "L’utilisateur semble évoquer ou proposer des activités interdites par la loi (trafic d’animaux, substances illicites, armes, etc.)."),
            SQRadioOption(title: "Option 3", desc: "L’utilisateur semble fournir de fausses informations dans son profil."),
            SQRadioOption(title: "Option 4", desc: "L’utilisateur semble avoir usurpé mon identité ou l’identité d’un autre utilisateur (SIRET, numéro de téléphone...).")
        ], selectedIndex: .constant(0), error: .constant(.custom("Merci de détailler votre signalement")))

        SQRadio(title: "Horizontal", orientation: .horizontal, options: [
            SQRadioOption(title: "1\n Non Jamais"),
            SQRadioOption(title: "2"),
            SQRadioOption(title: "3"),
            SQRadioOption(title: "4"),
            SQRadioOption(title: "5\nOui")
        ], selectedIndex: .constant(2))
    }
    .padding()
}
