package models

import (
	"encoding/json"
	"fmt"
)

type DealReq struct {
	Name               string         `json:"name"`                     // название сделки
	Price              int            `json:"price"`                    // бюджет сделки
	StatusID           int32          `json:"status_id"`                // id статуса (шага в нашем случае) в который добавляется сделка
	PipelineID         int32          `json:"pipeline_id"`              // ID воронки, в которую добавляется сделка
	CreatedBy          int32          `json:"created_by"`               // id пользователя amoid который создает сделку (тот кто подключил интеграцию)
	UpdatedBy          int            `json:"updated_by"`               // ID пользователя, изменяющий сделку. При передаче значения 0, сделка будет считаться измененной роботом
	ClosedAt           int64          `json:"closed_at"`                // Дата закрытия сделки, передается в Unix Timestamp
	CreatedAt          int64          `json:"created_at"`               // Дата создания сделки, передается в Unix Timestamp
	UpdatedAt          int64          `json:"updated_at"`               // Дата изменения сделки, передается в Unix Timestamp
	LossReasonID       *int           `json:"loss_reason_id,omitempty"` // ID причины отказа
	ResponsibleUserID  int32          `json:"responsible_user_id"`      // ID пользователя, ответственного за сделку, в нашем случае PerformerID
	CustomFieldsValues []FieldsValues `json:"custom_fields_values"`     // Массив полей которые заполняются значениями
	TagsToAdd          []Tag          `json:"tags_to_add"`              // Массив тегов для добавления
	Embed              Embedd         `json:"_embedded"`
	RequestID          string         `json:"request_id"`
}

type ValueInterface interface{}

type FieldsValues struct {
	FieldID int              `json:"field_id"`
	Values  []ValueInterface `json:"values"`
}

type Values struct {
	Value string `json:"value"` // пока так пока не понятно
}

type ValuesFile struct {
	Value ValueFile `json:"value"`
}
type ValueFile struct {
	FileUUID    string `json:"file_uuid"`
	VersionUUID string `json:"version_uuid"`
	FileName    string `json:"file_name"`
	FileSize    int64  `json:"file_size"`
}

func (fv *FieldsValues) UnmarshalJSON(data []byte) error {
	type Alias FieldsValues
	aux := struct {
		Alias
		FieldID int               `json:"field_id"`
		Values  []json.RawMessage `json:"values"`
	}{}

	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}

	fv.FieldID = aux.FieldID
	fv.Values = make([]ValueInterface, len(aux.Values))

	for i, rawVal := range aux.Values {
		var v map[string]interface{}
		if err := json.Unmarshal(rawVal, &v); err != nil {
			return err
		}

		if _, ok := v["value"]; !ok {
			return fmt.Errorf("missing value in JSON")
		}

		var value ValueInterface
		if _, ok := v["value"].(map[string]interface{}); ok {
			var fileStruct ValuesFile
			if err := json.Unmarshal(rawVal, &fileStruct); err != nil {
				return err
			}
			value = fileStruct
		} else {
			var valValue Values
			if err := json.Unmarshal(rawVal, &valValue); err != nil {
				return err
			}
			value = valValue
		}

		fv.Values[i] = value
	}

	return nil
}

type Embedd struct {
	Tags    []Tag     `json:"tags"`      // Данные тегов, добавляемых к сделке
	Contact []Contact `json:"contacts"`  // Данные контактов, которые будет прикреплены к сделке
	Company []Company `json:"companies"` // Данные компании, которая будет прикреплена к сделке
	Source  Source    `json:"source"`
}

type Contact struct {
	ID                 int32          `json:"id"`
	Name               string         `json:"first_name"`
	ResponsibleUserID  int32          `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID
	CreatedBy          int32          `json:"created_by"`          // id пользователя amoid который создает сделку (тот кто подключил интеграцию)
	UpdatedBy          int            `json:"updated_by"`
	CreatedAt          int64          `json:"created_at"`
	UpdatedAt          int64          `json:"updated_at"`           // Дата изменения сделки, передается в Unix Timestamp
	CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
}

type Company struct {
	Name               string         `json:"name"`                // Название компании
	ResponsibleUserID  int32          `json:"responsible_user_id"` // ID пользователя, ответственного за сделку, в нашем случае PerformerID
	CreatedBy          int32          `json:"created_by"`          // id пользователя amoid который создает сделку (тот кто подключил интеграцию)
	UpdatedBy          int            `json:"updated_by"`
	CreatedAt          int64          `json:"created_at"`
	UpdatedAt          int64          `json:"updated_at"`           // Дата изменения сделки, передается в Unix Timestamp
	CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
}

type Source struct {
	ExternalID int    `json:"external_id"` // Внешний ID источника
	Type       string `json:"type"`        // Тип источника. Для сделок, добавляемых интеграциями, поддерживается только widget
}

type DealResp struct {
	DealID    int32    `json:"id"`         // ID сделки
	ContactID int      `json:"contact_id"` // ID контакта
	CompanyID int      `json:"company_id"` // ID компании
	Merged    bool     `json:"merged"`     // Флаг, который показывает, найден дубль подходящий под условия поиска дублей и произведено объединение или нет
	RequestID []string `json:"request_id"` // Массив строк с пользовательскими идентификаторами, которые были переданы с каждой сущностью
}

type UpdateDealReq struct {
	DealID             int32          `json:"id"`                   // ID сделки
	CustomFieldsValues []FieldsValues `json:"custom_fields_values"` // Массив полей которые заполняются значениями
}

type UpdateDealResp struct {
	Embedded EmbeddedUpdateDeal `json:"_embedded"`
}

type EmbeddedUpdateDeal struct {
	Leads []struct {
		ID        int32 `json:"id"`
		UpdatedAt int64 `json:"updated_at"`
	}
}

type Customer struct {
	Name              string         `json:"name"`
	NextPrice         int            `json:"next_price"`
	NextDate          int64          `json:"next_date"`
	ResponsibleUserID int32          `json:"responsible_user_id"`
	StatusID          *int32         `json:"status_id,omitempty"`
	Periodicity       int            `json:"periodicity"`
	CreatedBy         int            `json:"created_by"`
	UpdatedBy         int            `json:"updated_by"`
	CreatedAt         int64          `json:"created_at"`
	UpdatedAt         int64          `json:"updated_at"`
	CustomFields      []FieldsValues `json:"custom_fields_values"`
	TagsToAdd         []Tag          `json:"tags_to_add"`
	Embed             Embedd         `json:"_embedded"`
	RequestID         string         `json:"request_id"`
}

type CustomerResp struct {
	Embedded EmbeddedCreateCustomers `json:"_embedded"`
}

type EmbeddedCreateCustomers struct {
	Customers []struct {
		ID        int32  `json:"id"`
		RequestID string `json:"request_id"`
	}
}

type CreateSession struct {
	FileName    string `json:"file_name"`    // обязательное поле
	FileSize    int64  `json:"file_size"`    // обязательное поле
	FileUUID    string `json:"file_uuid"`    // UUID файла, для которого загружается новая версия файла. Если UUID не задан, то будет создан новый файл.
	ContentType string `json:"content_type"` // MIME-тип файла
	WithPreview bool   `json:"with_preview"` // При установке данного флага для файла будет сгенерировано превью
}

// представляет данные о созданной сессии загрузки файла
type UploadSession struct {
	SessionID   int    `json:"session_id"`
	UploadURL   string `json:"upload_url"`
	MaxFileSize int64  `json:"max_file_size"`
	MaxPartSize int64  `json:"max_part_size"`
}

// представляет информацию о загруженном файле
type UploadedFile struct {
	UUID                string `json:"uuid"`
	Type                string `json:"type"`
	IsTrashed           bool   `json:"is_trashed"`
	Name                string `json:"name"`
	SanitizedName       string `json:"sanitized_name"`
	Size                int64  `json:"size"`
	SourceID            int    `json:"source_id"`
	VersionUUID         string `json:"version_uuid"`
	HasMultipleVersions bool   `json:"has_multiple_versions"`
	CreatedAt           int64  `json:"created_at"`
	CreatedBy           struct {
		ID   int    `json:"id"`
		Type string `json:"type"`
	} `json:"created_by"`
	UpdatedAt int64         `json:"updated_at"`
	DeletedAt int64         `json:"deleted_at"`
	DeletedBy interface{}   `json:"deleted_by"`
	Metadata  Metadata      `json:"metadata"`
	Previews  []PreviewFile `json:"previews"`
}

type Metadata struct {
	Extension string `json:"extension"`
	MIMEType  string `json:"mime_type"`
}

type PreviewFile struct {
	DownloadLink string `json:"download_link"`
	Width        int    `json:"width"`
	Height       int    `json:"height"`
}
