package integration

import (
	"strconv"

	dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
)

type (
	Candidate struct {
		Id       string
		Name     string
		Email    string
		Phone    string
		Birthday string
		Info     string
		CvLink   string
	}

	HandleVacancy struct {
		AgentId   string
		VacancyId string
		SourceLid string
		Candidate Candidate
	}
)

type FieldType string

const (
	BooleanFieldType FieldType = "bool"
	IntegerFieldType FieldType = "int"
	FloatFieldType   FieldType = "float"
	StringFieldType  FieldType = "string"
	StructFieldType  FieldType = "struct"
)

func convertFieldtype(typ FieldType, value string) (any, error) {
	switch typ {
	case BooleanFieldType:
		return strconv.ParseBool(value)
	case IntegerFieldType:
		return strconv.ParseInt(value, 10, 64)
	case FloatFieldType:
		return strconv.ParseFloat(value, 64)
	case StringFieldType:
		return value, nil
	case StructFieldType:
		// TODO: maybe convert it to map[string]any?
		return value, nil
	default:
		return nil, ErrUnknownFieldType
	}
}

type (
	CompanyMetadata map[string]string

	ValidValue struct {
		DisplayName string `json:"display_name"`
		Value       string `json:"value"`
	}

	/*
		CompanyExtraFieldTemplate describes single
		additional field of company additional fields template
	*/
	CompanyExtraFieldTemplate struct {
		SystemName     string       `json:"system_name"`
		DisplayName    string       `json:"display_name"`
		Type           FieldType    `json:"type"`
		Required       bool         `json:"required"`
		MultipleChoice bool         `json:"multiple_choice"`
		ValidValues    []ValidValue `json:"valid_values"`
	}

	/*
		CompanyExtraFieldsTemplate describes additional fields
		needed to integrate company
	*/
	CompanyExtraFieldsTemplate struct {
		Fields []CompanyExtraFieldTemplate `json:"fields"`
	}

	/*
		CompanyIntegrationInfo describes full metadata stored for company
	*/
	CompanyIntegrationInfo struct {
		Metadata            CompanyMetadata            `json:"metadata"`
		ExtraFieldsTemplate CompanyExtraFieldsTemplate `json:"template"`
	}
)

func (m *CompanyMetadata) From(msg *dbtypes.CompanyMetadata) *CompanyMetadata {
	if msg == nil {
		return nil
	}

	for k, v := range *msg {
		(*m)[k] = v
	}

	return m
}

func (t *CompanyExtraFieldsTemplate) From(msg *dbtypes.CompanyExtraFieldsTemplate) *CompanyExtraFieldsTemplate {
	if msg == nil {
		return nil
	}

	var res CompanyExtraFieldsTemplate

	res.Fields = make([]CompanyExtraFieldTemplate, len(msg.Fields))

	for i, v := range msg.Fields {
		res.Fields[i] = CompanyExtraFieldTemplate{
			SystemName:     v.SystemName,
			DisplayName:    v.DisplayName,
			Type:           FieldType(v.Type),
			Required:       v.Required,
			MultipleChoice: v.MultipleChoice,
			ValidValues:    make([]ValidValue, len(v.ValidValues)),
		}

		for j, vv := range v.ValidValues {
			res.Fields[i].ValidValues[j] = ValidValue{
				DisplayName: vv.DisplayName,
				Value:       vv.Value,
			}
		}
	}

	return &res
}

type (
	/*
		VacancyExtraField describes single filled
		additional field of vacancy additional fields
	*/
	VacancyExtraField struct {
		SystemName     string    `json:"system_name"`
		Type           FieldType `json:"type"`
		MultipleChoice bool      `json:"multiple_choice"`
		IsValidValue   bool      `json:"is_valid_value"`
		Value          []string  `json:"value"`
	}

	/*
		VacancyExtraFields describes additional fields
		filled during vacancy creation
	*/
	VacancyExtraFields struct {
		Fields []VacancyExtraField `json:"fields"`
	}

	/*
		VacancyIntegrationInfo describes full metadata stored for vacancy
	*/
	VacancyIntegrationInfo struct {
		CompanyId   string             `json:"company_id"`
		ExtraFields VacancyExtraFields `json:"extra_fields"`
	}
)

func (f *VacancyExtraField) From(msg *dbtypes.VacancyExtraFieldTemplate) *VacancyExtraField {
	if msg == nil {
		return nil
	}

	res := VacancyExtraField{
		SystemName:   msg.SystemName,
		Type:         FieldType(msg.Type),
		IsValidValue: msg.IsValidValue,
		Value:        msg.Value,
	}

	return &res
}

func (f *VacancyExtraFields) From(msg *dbtypes.VacancyExtraFieldsTemplate) *VacancyExtraFields {
	if msg == nil {
		return nil
	}

	var res VacancyExtraFields

	res.Fields = make([]VacancyExtraField, len(msg.Fields))

	for i, v := range msg.Fields {
		res.Fields[i] = *new(VacancyExtraField).From(&v)
	}

	return &res
}

const (
	companyNameMetadataKey = "company_name"

	VkusvillCompanyName = "vkusvill"
)
