import { Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { NonNullableFormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'
import { ActivatedRoute, Router } from '@angular/router'
import { CreateTenantWithUserRequest, DefaultService } from '@api-client/angular'
import { LoadingButtonDirective } from '@frontend/shared'
import { TranslocoDirective } from '@jsverse/transloco'
import { NgLabelTemplateDirective, NgOptionTemplateDirective, NgSelectComponent } from '@ng-select/ng-select'
import { HotToastService } from '@ngxpert/hot-toast'
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'
import { finalize } from 'rxjs'
import { PlacesAutocompleteComponent } from '../../shared/components/places-autocomplete.component'

@UntilDestroy({ checkProperties: true })
@Component({
	selector: 'kadi-onboarding',
	templateUrl: 'onboarding.component.html',
	imports: [
		TranslocoDirective,
		ReactiveFormsModule,
		NgSelectComponent,
		NgOptionTemplateDirective,
		NgLabelTemplateDirective,
		PlacesAutocompleteComponent,
		LoadingButtonDirective,
	],
})
export class OnboardingComponent {
	private readonly _router = inject(Router)
	private readonly _toast = inject(HotToastService)
	private readonly _apiService = inject(DefaultService)
	private readonly _activeRoute = inject(ActivatedRoute)
	private readonly _formBuilder = inject(NonNullableFormBuilder)

	loading = false
	verificationLoading = true

	form = this._formBuilder.group({
		verificationToken: this._formBuilder.control('', Validators.required),
		companyName: this._formBuilder.control('', {
			validators: [Validators.required, Validators.minLength(2), Validators.maxLength(30)],
		}),
		currencyCode: this._formBuilder.control('EUR', {
			validators: [Validators.required, Validators.minLength(3), Validators.maxLength(3)],
		}),
		contactEmail: this._formBuilder.control('', {
			validators: [Validators.required, Validators.email],
		}),
		address: this._formBuilder.control('', Validators.required),
		googlePlaceId: this._formBuilder.control('', Validators.required),
		timezone: this._formBuilder.control('Europe/Berlin', Validators.required),
		user: this._formBuilder.group({
			firstName: this._formBuilder.control('', {
				validators: [Validators.required, Validators.minLength(2), Validators.maxLength(60)],
			}),
			lastName: this._formBuilder.control('', {
				validators: [Validators.required, Validators.minLength(2), Validators.maxLength(60)],
			}),
			email: this._formBuilder.control('', {
				validators: [Validators.required, Validators.email],
			}),
			password: this._formBuilder.control('', {
				validators: [Validators.required, Validators.minLength(8)],
			}),
		}),
	})

	currencyList = toSignal(this._apiService.staticControllerGetCurrencies())
	timezoneList = toSignal(this._apiService.staticControllerGetTimezones())

	constructor() {
		const token = this._activeRoute.snapshot.queryParamMap.get('token')
		if (token) this.verifyToken(token)
		else this._router.navigateByUrl('/auth/login')
	}

	save(): void {
		if (this.form.invalid) return

		const request = this.form.getRawValue()

		this.loading = true
		this._apiService
			.tenantControllerCreateTenant(request as CreateTenantWithUserRequest)
			.pipe(
				untilDestroyed(this),
				finalize(() => (this.loading = false)),
			)
			.subscribe({
				next: () => {
					this._toast.success('Your account has been successfully setup, redirecting to login...', { duration: 5000 })
					this._router.navigateByUrl('/auth/login')
				},
			})
	}

	onGoogleAddressChanged(address: google.maps.places.PlaceResult): void {
		if (!address.formatted_address || !address.place_id) {
			this._toast.warning('Invalid address selected, please try another')
			return
		}

		this.form.controls.address.setValue(address.formatted_address)
		this.form.controls.googlePlaceId.setValue(address.place_id)

		console.log(address.place_id)
	}

	private verifyToken(token: string): void {
		this._apiService
			.authControllerVerifyEmailToken({ token })
			.pipe(
				untilDestroyed(this),
				finalize(() => (this.verificationLoading = false)),
			)
			.subscribe({
				next: ({ email }) => {
					this.form.controls.verificationToken.setValue(token)
					this.form.controls.user.controls.email.setValue(email)
					this.form.controls.user.controls.email.disable()
				},
				error: (error) => {
					this._toast.error(error.message)
				},
			})
	}
}
