package api

import (
	"strings"
	"time"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"wucher/internal/domain/auth"
	"wucher/internal/domain/base"
)

// SeedRoles inserts default roles if they don't exist.
func SeedRoles(db *gorm.DB) error {
	roles := []auth.Role{
		{Code: "admin", Name: "admin", Description: "Full access to all resources."},
		{Code: auth.RoleCodeStaff, Name: auth.RoleCodeStaff, Description: "Operational access with limited admin rights."},
		{Code: "user", Name: "user", Description: "Regular end-user access."},
		{Code: auth.RoleCodePilot, Name: "pilot", Description: "HEMS pilot contact role."},
		{Code: auth.RoleCodeDoctor, Name: "doctor", Description: "HEMS doctor contact role."},
		{Code: auth.RoleCodeAirRescuer, Name: "air_rescuer", Description: "HEMS air rescuer contact role."},
		{Code: auth.RoleCodeTechnician, Name: "technician", Description: "HEMS technician contact role."},
		{Code: auth.RoleCodeFlightAssistant, Name: "flight_assistant", Description: "HEMS flight assistant contact role."},
	}

	return db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "name"}},
		DoUpdates: clause.AssignmentColumns([]string{"code", "description"}),
	}).Create(&roles).Error
}

// DefaultPermissions returns the canonical catalog of permissions seeded into the system.
func DefaultPermissions() []auth.Permission {
	return []auth.Permission{
		{Name: "Create User", Key: "user.create", Description: "Create users"},
		{Name: "Read User", Key: "user.read", Description: "Read users"},
		{Name: "Update User", Key: "user.update", Description: "Update users"},
		{Name: "Delete User", Key: "user.delete", Description: "Delete users"},
		{Name: "Create Role", Key: "role.create", Description: "Create roles"},
		{Name: "Read Role", Key: "role.read", Description: "Read roles"},
		{Name: "Update Role", Key: "role.update", Description: "Update roles"},
		{Name: "Delete Role", Key: "role.delete", Description: "Delete roles"},
		{Name: "Read Permission", Key: "role.permission.read", Description: "Read permissions"},
		{Name: "Assign Permission", Key: "role.permission.assign", Description: "Assign permissions to role"},
		{Name: "Remove Permission", Key: "role.permission.remove", Description: "Remove permissions from role"},
		{Name: "Update Permission", Key: "role.permission.update", Description: "Update permission configuration"},
		{Name: "Read Filesystem", Key: "filesystem.read", Description: "Read filesystem structure"},
		{Name: "Read File Manager", Key: "file_manager.read", Description: "Read file manager"},
		{Name: "Create File Manager", Key: "file_manager.create", Description: "Create in file manager"},
		{Name: "Update File Manager", Key: "file_manager.update", Description: "Update in file manager"},
		{Name: "Delete File Manager", Key: "file_manager.delete", Description: "Delete in file manager"},
		{Name: "Read Folders", Key: "file_manager.folder.read", Description: "Read folders"},
		{Name: "Create Folders", Key: "file_manager.folder.create", Description: "Create folders"},
		{Name: "Update Folders", Key: "file_manager.folder.update", Description: "Update folders"},
		{Name: "Delete Folders", Key: "file_manager.folder.delete", Description: "Delete folders"},
		{Name: "Read Files", Key: "file_manager.file.read", Description: "Read files"},
		{Name: "Create Files", Key: "file_manager.file.create", Description: "Create files"},
		{Name: "Update Files", Key: "file_manager.file.update", Description: "Update files"},
		{Name: "Delete Files", Key: "file_manager.file.delete", Description: "Delete files"},
		{Name: "Create Helicopter", Key: "helicopter.create", Description: "Create helicopter"},
		{Name: "Generate Helicopter Report Number", Key: "helicopter.report.generate", Description: "Generate next helicopter report number"},
		{Name: "Read Helicopter", Key: "helicopter.read", Description: "Read helicopter"},
		{Name: "Update Helicopter", Key: "helicopter.update", Description: "Update helicopter"},
		{Name: "Delete Helicopter", Key: "helicopter.delete", Description: "Delete helicopter"},
		{Name: "Create Helicopter Usage", Key: "helicopter_usage.create", Description: "Create helicopter usage"},
		{Name: "Read Helicopter Usage", Key: "helicopter_usage.read", Description: "Read helicopter usage"},
		{Name: "Update Helicopter Usage", Key: "helicopter_usage.update", Description: "Update helicopter usage"},
		{Name: "Delete Helicopter Usage", Key: "helicopter_usage.delete", Description: "Delete helicopter usage"},
		{Name: "Create Flight Inspection", Key: "flight_inspection.create", Description: "Create flight inspection"},
		{Name: "Read Flight Inspection", Key: "flight_inspection.read", Description: "Read flight inspection"},
		{Name: "Update Flight Inspection", Key: "flight_inspection.update", Description: "Update flight inspection"},
		{Name: "Create After Flight Inspection", Key: "after_flight.create", Description: "Create after flight inspection"},
		{Name: "Read After Flight Inspection", Key: "after_flight.read", Description: "Read after flight inspection"},
		{Name: "Update After Flight Inspection", Key: "after_flight.update", Description: "Update after flight inspection"},
		{Name: "Delete After Flight Inspection", Key: "after_flight.delete", Description: "Delete after flight inspection"},
		{Name: "Create Flight", Key: "flight.create", Description: "Create flight"},
		{Name: "Read Flight", Key: "flight.read", Description: "Read flight"},
		{Name: "Update Flight", Key: "flight.update", Description: "Update flight"},
		{Name: "Complete Flight Report", Key: "flight.complete", Description: "Complete (finalize) flight report"},
		{Name: "Delete Flight", Key: "flight.delete", Description: "Delete flight"},
		{Name: "Create Reserve AC", Key: "reserve_ac.create", Description: "Create reserve AC"},
		{Name: "Read Reserve AC", Key: "reserve_ac.read", Description: "Read reserve AC"},
		{Name: "Update Reserve AC", Key: "reserve_ac.update", Description: "Update reserve AC"},
		{Name: "Delete Reserve AC", Key: "reserve_ac.delete", Description: "Delete reserve AC"},
		{Name: "Create Facility", Key: "facility.create", Description: "Create facility"},
		{Name: "Read Facility", Key: "facility.read", Description: "Read facility"},
		{Name: "Update Facility", Key: "facility.update", Description: "Update facility"},
		{Name: "Delete Facility", Key: "facility.delete", Description: "Delete facility"},
		{Name: "Create Base", Key: "base.create", Description: "Create base"},
		{Name: "Read Base", Key: "base.read", Description: "Read base"},
		{Name: "Update Base", Key: "base.update", Description: "Update base"},
		{Name: "Delete Base", Key: "base.delete", Description: "Delete base"},
		{Name: "Create HEMS Base", Key: "hems_base.create", Description: "Create HEMS base"},
		{Name: "Read HEMS Base", Key: "hems_base.read", Description: "Read HEMS base"},
		{Name: "Update HEMS Base", Key: "hems_base.update", Description: "Update HEMS base"},
		{Name: "Delete HEMS Base", Key: "hems_base.delete", Description: "Delete HEMS base"},
		{Name: "Create Medicine", Key: "medicine.create", Description: "Create medicine"},
		{Name: "Read Medicine", Key: "medicine.read", Description: "Read medicine"},
		{Name: "Update Medicine", Key: "medicine.update", Description: "Update medicine"},
		{Name: "Delete Medicine", Key: "medicine.delete", Description: "Delete medicine"},
		{Name: "Create Vocation", Key: "vocation.create", Description: "Create vocation"},
		{Name: "Read Vocation", Key: "vocation.read", Description: "Read vocation"},
		{Name: "Update Vocation", Key: "vocation.update", Description: "Update vocation"},
		{Name: "Delete Vocation", Key: "vocation.delete", Description: "Delete vocation"},
		{Name: "Create OPC", Key: "opc.create", Description: "Create opc"},
		{Name: "Read OPC", Key: "opc.read", Description: "Read opc"},
		{Name: "Update OPC", Key: "opc.update", Description: "Update opc"},
		{Name: "Delete OPC", Key: "opc.delete", Description: "Delete opc"},
		{Name: "Create Forces Present", Key: "forces_present.create", Description: "Create forces present"},
		{Name: "Read Forces Present", Key: "forces_present.read", Description: "Read forces present"},
		{Name: "Update Forces Present", Key: "forces_present.update", Description: "Update forces present"},
		{Name: "Delete Forces Present", Key: "forces_present.delete", Description: "Delete forces present"},
		{Name: "Create No ICAO Code", Key: "no_icao_code.create", Description: "Create no icao code"},
		{Name: "Read No ICAO Code", Key: "no_icao_code.read", Description: "Read no icao code"},
		{Name: "Update No ICAO Code", Key: "no_icao_code.update", Description: "Update no icao code"},
		{Name: "Delete No ICAO Code", Key: "no_icao_code.delete", Description: "Delete no icao code"},
		{Name: "Create Health Insurance Companies", Key: "health_insurance_companies.create", Description: "Create health insurance companies"},
		{Name: "Read Health Insurance Companies", Key: "health_insurance_companies.read", Description: "Read health insurance companies"},
		{Name: "Update Health Insurance Companies", Key: "health_insurance_companies.update", Description: "Update health insurance companies"},
		{Name: "Delete Health Insurance Companies", Key: "health_insurance_companies.delete", Description: "Delete health insurance companies"},
		{Name: "Create Federal State", Key: "federal_state.create", Description: "Create federal state"},
		{Name: "Read Federal State", Key: "federal_state.read", Description: "Read federal state"},
		{Name: "Update Federal State", Key: "federal_state.update", Description: "Update federal state"},
		{Name: "Delete Federal State", Key: "federal_state.delete", Description: "Delete federal state"},
		{Name: "Create ICAO", Key: "icao.create", Description: "Create ICAO"},
		{Name: "Read ICAO", Key: "icao.read", Description: "Read ICAO"},
		{Name: "Update ICAO", Key: "icao.update", Description: "Update ICAO"},
		{Name: "Delete ICAO", Key: "icao.delete", Description: "Delete ICAO"},
		{Name: "Create Country", Key: "country.create", Description: "Create country"},
		{Name: "Read Country", Key: "country.read", Description: "Read country"},
		{Name: "Update Country", Key: "country.update", Description: "Update country"},
		{Name: "Delete Country", Key: "country.delete", Description: "Delete country"},
		{Name: "Create Master Settings", Key: "master_settings.create", Description: "Create master settings"},
		{Name: "Read Master Settings", Key: "master_settings.read", Description: "Read master settings"},
		{Name: "Update Master Settings", Key: "master_settings.update", Description: "Update master settings"},
		{Name: "Delete Master Settings", Key: "master_settings.delete", Description: "Delete master settings"},
		{Name: "Create Duty Roster", Key: "duty_roster.create", Description: "Create duty roster"},
		{Name: "Read Duty Roster", Key: "duty_roster.read", Description: "Read duty roster"},
		{Name: "Update Duty Roster", Key: "duty_roster.update", Description: "Update duty roster"},
		{Name: "Delete Duty Roster", Key: "duty_roster.delete", Description: "Delete duty roster"},
		{Name: "Create Air Rescuer Checklist", Key: "air_rescuer_checklist.create", Description: "Create air rescuer checklist"},
		{Name: "Read Air Rescuer Checklist", Key: "air_rescuer_checklist.read", Description: "Read air rescuer checklist"},
		{Name: "Update Air Rescuer Checklist", Key: "air_rescuer_checklist.update", Description: "Update air rescuer checklist"},
		{Name: "Delete Air Rescuer Checklist", Key: "air_rescuer_checklist.delete", Description: "Delete air rescuer checklist"},
		{Name: "Create Flight Prep Check", Key: "flight_prep_check.create", Description: "Create flight prep check"},
		{Name: "Read Flight Prep Check", Key: "flight_prep_check.read", Description: "Read flight prep check"},
		{Name: "Update Flight Prep Check", Key: "flight_prep_check.update", Description: "Update flight prep check"},
		{Name: "Read Audit Log", Key: "audit.read", Description: "Read audit logs"},
		{Name: "Create Insurance Patient Data", Key: "insurance_patient_data.create", Description: "Create insurance patient data"},
		{Name: "Read Insurance Patient Data", Key: "insurance_patient_data.read", Description: "Read insurance patient data"},
		{Name: "Update Insurance Patient Data", Key: "insurance_patient_data.update", Description: "Update insurance patient data"},
		{Name: "Delete Insurance Patient Data", Key: "insurance_patient_data.delete", Description: "Delete insurance patient data"},
		{Name: "Create Patient Data", Key: "patient_data.create", Description: "Create patient data"},
		{Name: "Read Patient Data", Key: "patient_data.read", Description: "Read patient data"},
		{Name: "Update Patient Data", Key: "patient_data.update", Description: "Update patient data"},
		{Name: "Delete Patient Data", Key: "patient_data.delete", Description: "Delete patient data"},
		{Name: "Create Operation", Key: "operation.create", Description: "Create HEMS operational data"},
		{Name: "Read Operation", Key: "operation.read", Description: "Read HEMS operational data"},
		{Name: "Update Operation", Key: "operation.update", Description: "Update HEMS operational data"},
		{Name: "Delete Operation", Key: "operation.delete", Description: "Delete HEMS operational data"},
		{Name: "Create Operation Category", Key: "operation_category.create", Description: "Create HEMS operation category"},
		{Name: "Read Operation Category", Key: "operation_category.read", Description: "Read HEMS operation category"},
		{Name: "Update Operation Category", Key: "operation_category.update", Description: "Update HEMS operation category"},
		{Name: "Delete Operation Category", Key: "operation_category.delete", Description: "Delete HEMS operation category"},
		{Name: "Create HEMS Operation", Key: "hems_operation.create", Description: "Create HEMS operation"},
		{Name: "Read HEMS Operation", Key: "hems_operation.read", Description: "Read HEMS operation"},
		{Name: "Update HEMS Operation", Key: "hems_operation.update", Description: "Update HEMS operation"},
		{Name: "Delete HEMS Operation", Key: "hems_operation.delete", Description: "Delete HEMS operation"},
		{Name: "Create DUL", Key: "dul.create", Description: "Create DUL"},
		{Name: "Read DUL", Key: "dul.read", Description: "Read DUL"},
		{Name: "Update DUL", Key: "dul.update", Description: "Update DUL"},
		{Name: "Delete DUL", Key: "dul.delete", Description: "Delete DUL"},
		{Name: "Create Complaint", Key: "complaint.create", Description: "Create complaint"},
		{Name: "Read Complaint", Key: "complaint.read", Description: "Read complaint"},
		{Name: "Update Complaint", Key: "complaint.update", Description: "Update complaint"},
		{Name: "Delete Complaint", Key: "complaint.delete", Description: "Delete complaint"},
		{Name: "Decide Complaint NSR", Key: "complaint.nsr", Description: "Set or cancel complaint NSR (non-safety release)"},
		{Name: "Create EASA Release", Key: "easa_release.create", Description: "Create EASA maintenance release"},
		{Name: "Read EASA Release", Key: "easa_release.read", Description: "Read EASA maintenance release"},
		{Name: "Update EASA Release", Key: "easa_release.update", Description: "Update EASA maintenance release"},
		{Name: "Delete EASA Release", Key: "easa_release.delete", Description: "Delete EASA maintenance release"},
		{Name: "Sign EASA Release", Key: "easa_release.sign", Description: "Sign EASA maintenance release (return to service)"},
		{Name: "Read Action Sign-off", Key: "action_signoff.read", Description: "Read corrective-action sign-off"},
		{Name: "Sign Action Sign-off", Key: "action_signoff.sign", Description: "Toggle (sign/unsign) corrective-action sign-off, per complaint or fleet-wide"},
		{Name: "Create MCF", Key: "mcf.create", Description: "Create maintenance check flight"},
		{Name: "Read MCF", Key: "mcf.read", Description: "Read maintenance check flight"},
		{Name: "Complete MCF", Key: "mcf.complete", Description: "Complete (release) a helicopter's open maintenance check flight"},
	}
}

// SeedPermissions inserts default permissions and keeps existing rows in sync.
func SeedPermissions(db *gorm.DB) error {
	perms := DefaultPermissions()

	for i := range perms {
		perms[i].Module = auth.ModuleForKey(perms[i].Key)
		perms[i].RequiresPIN = auth.DefaultPermissionRequiresPIN(perms[i].Key)
	}

	return db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "key"}},
		DoUpdates: clause.AssignmentColumns([]string{"name", "description", "module"}),
	}).Create(&perms).Error
}

// SeedRolePermissions inserts default role-permission mappings and ensures admin has all permissions.
func SeedRolePermissions(db *gorm.DB) error {
	type rolePerm struct {
		RoleName string
		PermKey  string
	}

	mappings := []rolePerm{
		// staff: read-only for users/roles/permissions
		{RoleName: "staff", PermKey: "user.read"},
		{RoleName: "staff", PermKey: "role.read"},
		{RoleName: "staff", PermKey: "role.permission.read"},
		{RoleName: "staff", PermKey: "helicopter.read"},
		{RoleName: "staff", PermKey: "flight_inspection.read"},
		{RoleName: "staff", PermKey: "flight.read"},
		{RoleName: "staff", PermKey: "reserve_ac.read"},
		{RoleName: "staff", PermKey: "facility.read"},
		{RoleName: "staff", PermKey: "base.read"},
		{RoleName: "staff", PermKey: "hems_base.read"},
		{RoleName: "staff", PermKey: "medicine.read"},
		{RoleName: "staff", PermKey: "vocation.read"},
		{RoleName: "staff", PermKey: "opc.read"},
		{RoleName: "staff", PermKey: "forces_present.read"},
		{RoleName: "staff", PermKey: "no_icao_code.read"},
		{RoleName: "staff", PermKey: "health_insurance_companies.read"},
		{RoleName: "staff", PermKey: "federal_state.read"},
		{RoleName: "staff", PermKey: "icao.read"},
		{RoleName: "staff", PermKey: "country.read"},
		{RoleName: "staff", PermKey: "master_settings.read"},
		{RoleName: "staff", PermKey: "file_manager.read"},
		{RoleName: "staff", PermKey: "duty_roster.read"},
		{RoleName: "staff", PermKey: "air_rescuer_checklist.read"},
		{RoleName: "staff", PermKey: "flight_prep_check.create"},
		{RoleName: "staff", PermKey: "flight_prep_check.read"},
		{RoleName: "staff", PermKey: "flight_prep_check.update"},
		{RoleName: "staff", PermKey: "helicopter_usage.read"},
		{RoleName: "staff", PermKey: "after_flight.read"},
		{RoleName: "staff", PermKey: "audit.read"},
		{RoleName: "staff", PermKey: "insurance_patient_data.read"},
		{RoleName: "staff", PermKey: "patient_data.read"},
		{RoleName: "staff", PermKey: "operation.read"},
		{RoleName: "staff", PermKey: "operation_category.read"},
		{RoleName: "staff", PermKey: "hems_operation.read"},
		{RoleName: "pilot", PermKey: "flight.read"},
		{RoleName: "pilot", PermKey: "duty_roster.read"},
	}

	if err := assignAllPermissionsToRole(db, "admin"); err != nil {
		return err
	}

	for _, m := range mappings {
		if err := assignPermissionToRole(db, m.RoleName, m.PermKey); err != nil {
			return err
		}
	}
	return nil
}

func assignAllPermissionsToRole(db *gorm.DB, roleName string) error {
	var role auth.Role
	if err := db.Where("name = ?", roleName).First(&role).Error; err != nil {
		return err
	}

	var perms []auth.Permission
	if err := db.Find(&perms).Error; err != nil {
		return err
	}

	for _, perm := range perms {
		rp := auth.RolePermission{RoleID: role.ID, PermissionID: perm.ID}
		if err := db.Clauses(clause.OnConflict{
			Columns:   []clause.Column{{Name: "role_id"}, {Name: "permission_id"}},
			DoNothing: true,
		}).Create(&rp).Error; err != nil {
			return err
		}
	}
	return nil
}

func assignPermissionToRole(db *gorm.DB, roleName, permKey string) error {
	var role auth.Role
	if err := db.Where("name = ?", roleName).First(&role).Error; err != nil {
		return err
	}
	var perm auth.Permission
	if err := db.Where("`key` = ?", permKey).First(&perm).Error; err != nil {
		return err
	}
	rp := auth.RolePermission{RoleID: role.ID, PermissionID: perm.ID}
	return db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "role_id"}, {Name: "permission_id"}},
		DoNothing: true,
	}).Create(&rp).Error
}

// SeedBaseCategories inserts default base categories if they don't exist.
func SeedBaseCategories(db *gorm.DB) error {
	categories := []base.BaseCategory{
		{Key: base.CategoryKeyRegular, Name: "Regular Base"},
		{Key: base.CategoryKeyHEMS, Name: "HEMS Base"},
	}

	return db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "key"}},
		DoUpdates: clause.AssignmentColumns([]string{"name"}),
	}).Create(&categories).Error
}

// SeedRosterUsers inserts sample users for duty roster assignment in development.
// This seed is idempotent by email and keeps role assignment synced via user_roles.
func SeedRosterUsers(db *gorm.DB) error {
	type rosterSeed struct {
		Email       string
		FirstName   string
		LastName    string
		MobilePhone string
		RoleCode    string
	}

	seeds := []rosterSeed{
		{Email: "pilot.main@wucher.local", FirstName: "Pilot", LastName: "Main", MobilePhone: "+620001", RoleCode: auth.RoleCodePilot},
		{Email: "pilot.additional@wucher.local", FirstName: "Pilot", LastName: "Additional", MobilePhone: "+620002", RoleCode: auth.RoleCodePilot},
		{Email: "doctor.main@wucher.local", FirstName: "Doctor", LastName: "Main", MobilePhone: "+620003", RoleCode: auth.RoleCodeDoctor},
		{Email: "rescuer.main@wucher.local", FirstName: "Rescuer", LastName: "Main", MobilePhone: "+620004", RoleCode: auth.RoleCodeAirRescuer},
		{Email: "helper.main@wucher.local", FirstName: "Helper", LastName: "Main", MobilePhone: "+620005", RoleCode: auth.RoleCodeFlightAssistant},
	}

	return db.Transaction(func(tx *gorm.DB) error {
		roleKeys := make([]string, 0, len(seeds))
		seenRole := make(map[string]struct{}, len(seeds))
		for i := range seeds {
			k := strings.ToLower(strings.TrimSpace(seeds[i].RoleCode))
			if k == "" {
				continue
			}
			if _, ok := seenRole[k]; ok {
				continue
			}
			seenRole[k] = struct{}{}
			roleKeys = append(roleKeys, k)
		}

		var roles []auth.Role
		if err := tx.Where("LOWER(code) IN ? OR LOWER(name) IN ?", roleKeys, roleKeys).Find(&roles).Error; err != nil {
			return err
		}
		roleIDByCode := make(map[string][]byte, len(roles))
		for i := range roles {
			code := strings.ToLower(strings.TrimSpace(roles[i].Code))
			if code == "" {
				code = strings.ToLower(strings.TrimSpace(roles[i].Name))
			}
			if code == "" {
				continue
			}
			roleIDByCode[code] = append([]byte(nil), roles[i].ID...)
		}

		now := time.Now().UTC()
		for i := range seeds {
			roleCode := strings.ToLower(strings.TrimSpace(seeds[i].RoleCode))
			roleID := roleIDByCode[roleCode]
			if len(roleID) != 16 {
				continue
			}

			row := auth.User{
				Email:           strings.ToLower(strings.TrimSpace(seeds[i].Email)),
				Username:        nil,
				FirstName:       strings.TrimSpace(seeds[i].FirstName),
				LastName:        strings.TrimSpace(seeds[i].LastName),
				MobilePhone:     strings.TrimSpace(seeds[i].MobilePhone),
				Timezone:        "UTC",
				RoleID:          roleID,
				IsActive:        true,
				EmailVerifiedAt: &now,
			}

			if err := tx.Clauses(clause.OnConflict{
				Columns: []clause.Column{{Name: "email"}},
				DoUpdates: clause.Assignments(map[string]any{
					"first_name":        row.FirstName,
					"last_name":         row.LastName,
					"mobile_phone":      row.MobilePhone,
					"timezone":          row.Timezone,
					"role_id":           row.RoleID,
					"is_active":         row.IsActive,
					"email_verified_at": row.EmailVerifiedAt,
					"updated_at":        now,
				}),
			}).Create(&row).Error; err != nil {
				return err
			}

			var created auth.User
			if err := tx.Where("email = ?", row.Email).Take(&created).Error; err != nil {
				return err
			}

			link := auth.UserRole{
				UserID: created.ID,
				RoleID: roleID,
			}
			if err := tx.Clauses(clause.OnConflict{
				Columns:   []clause.Column{{Name: "user_id"}, {Name: "role_id"}},
				DoNothing: true,
			}).Create(&link).Error; err != nil {
				return err
			}
		}

		return nil
	})
}
