package requestmodel

import (
	"fmt"

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

type AddNewAgentCompanyMemberRequest struct {
	Uid string `json:"uid"`
}

type EmployeeRequest struct {
	Uid string `json:"uid"`
}

type EmployeeResponse struct {
	CompanyID string           `json:"company_id"`
	Employees []types.Employee `json:"employees"`
}

type (
	Company struct {
		Id                  string   `json:"id"`
		OwnerId             string   `json:"owner_id"`
		Name                *string  `json:"name"`
		LegalPerson         *string  `json:"legal_person"`
		Description         *string  `json:"description"`
		Website             *string  `json:"website"`
		PhysicalAddress     *string  `json:"physical_address"`
		LegalAddress        *string  `json:"legal_address"`
		Inn                 *string  `json:"inn"`
		Kpp                 *string  `json:"kpp"`
		IsActive            bool     `json:"is_active"`
		HasModerationTicket bool     `json:"has_moderation_ticket"`
		Staff               []string `json:"staff"`
		Metadata            *string  `json:"metadata"`
		ExtraFieldsTemplate *string  `json:"extra_fields_template"`
	}
)

func (c *Company) From(msg *dbtypes.Company) *Company {
	if msg == nil {
		return nil
	}

	res := &Company{
		Id:                  msg.Id,
		OwnerId:             msg.OwnerId,
		Name:                msg.Name,
		LegalPerson:         msg.LegalPerson,
		Description:         msg.Description,
		Website:             msg.Website,
		PhysicalAddress:     msg.PhysicalAddress,
		LegalAddress:        msg.LegalAddress,
		Inn:                 msg.Inn,
		Kpp:                 msg.Kpp,
		IsActive:            msg.IsActive,
		HasModerationTicket: msg.HasModerationTicket,
		Staff:               msg.Staff,
		Metadata:            msg.Metadata,
		ExtraFieldsTemplate: msg.ExtraFieldsTemplate,
	}

	return res
}

type (
	CompanyListGetRequest struct {
		Id string
	}

	CompanyListGetResponse struct {
		Companies []Company `json:"companies"`
	}
)

func (r *CompanyListGetRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.Id == "" {
		return fmt.Errorf("%w: ID is required", ErrValidation)
	}

	return nil
}

func (r *CompanyListGetResponse) From(msg *dbtypes.CompanyListGetResponse) *CompanyListGetResponse {
	if msg == nil {
		return nil
	}

	res := &CompanyListGetResponse{
		Companies: make([]Company, len(msg.Companies)),
	}

	for i, company := range msg.Companies {
		res.Companies[i] = *new(Company).From(&company)
	}

	return res
}

type (
	CompanyByIdGetRequest struct {
		UserId    string
		CompanyId string
	}

	CompanyByIdGetResponse struct {
		Company Company `json:"company"`
	}
)

func (r *CompanyByIdGetRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.UserId == "" {
		return fmt.Errorf("%w: UserID is required", ErrValidation)
	}

	if r.CompanyId == "" {
		return fmt.Errorf("%w: CompanyID is required", ErrValidation)
	}

	return nil
}

func (r *CompanyByIdGetResponse) From(msg *dbtypes.CompanyByIdGetResponse) *CompanyByIdGetResponse {
	if msg == nil {
		return nil
	}

	return &CompanyByIdGetResponse{
		Company: *new(Company).From(&msg.Company),
	}
}

type (
	CompanyCreateRequest struct {
		OwnerId             string
		Name                *string  `json:"name"`
		LegalPerson         *string  `json:"legal_person"`
		Description         *string  `json:"description"`
		Website             *string  `json:"website"`
		PhysicalAddress     *string  `json:"physical_address"`
		LegalAddress        *string  `json:"legal_address"`
		Inn                 *string  `json:"inn"`
		Kpp                 *string  `json:"kpp"`
		Staff               []string `json:"staff"`
		Metadata            *string  `json:"metadata"`
		ExtraFieldsTemplate *string  `json:"extra_fields_template"`
	}

	CompanyCreateResponse struct {
		Id string `json:"id"`
	}
)

func (r *CompanyCreateRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.OwnerId == "" {
		return fmt.Errorf("%w: OwnerID is required", ErrValidation)
	}

	return nil
}

func (r *CompanyCreateResponse) From(msg *dbtypes.CompanyCreateResponse) *CompanyCreateResponse {
	if msg == nil {
		return nil
	}

	return &CompanyCreateResponse{
		Id: msg.Id,
	}
}

type (
	CompanyUpdateRequest struct {
		Id              string
		Name            *string  `json:"name"`
		LegalPerson     *string  `json:"legal_person"`
		Description     *string  `json:"description"`
		Website         *string  `json:"website"`
		PhysicalAddress *string  `json:"physical_address"`
		LegalAddress    *string  `json:"legal_address"`
		Inn             *string  `json:"inn"`
		Kpp             *string  `json:"kpp"`
		Staff           []string `json:"staff"`
		Metadata        *string  `json:"metadata"`
		ExtraFields     *string  `json:"extra_fields"`
	}

	CompanyUpdateResponse struct {
	}
)

func (r *CompanyUpdateRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.Id == "" {
		return fmt.Errorf("%w: ID is required", ErrValidation)
	}

	if r.Name == nil && r.LegalPerson == nil && r.Description == nil && r.Website == nil &&
		r.PhysicalAddress == nil && r.LegalAddress == nil && r.Inn == nil && r.Kpp == nil &&
		r.Staff == nil && r.Metadata == nil && r.ExtraFields == nil {
		return fmt.Errorf("%w: nothing to update", ErrValidation)
	}

	return nil
}

type (
	AddDistributorCompanyMemberRequest struct {
		Id        string `json:"id"`
		CompanyId string
	}

	AddDistributorCompanyMemberResponse struct {
	}
)

func (r *AddDistributorCompanyMemberRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.Id == "" {
		return fmt.Errorf("%w: ID is required", ErrValidation)
	}

	if r.CompanyId == "" {
		return fmt.Errorf("%w: CompanyID is required", ErrValidation)
	}

	return nil
}

type (
	CompanyDeleteRequest struct {
		Id string
	}

	CompanyDeleteResponse struct {
	}
)

func (r *CompanyDeleteRequest) Validate() error {
	if r == nil {
		return fmt.Errorf("%w: request is nil", ErrValidation)
	}

	if r.Id == "" {
		return fmt.Errorf("%w: ID is required", ErrValidation)
	}

	return nil
}
