package inquiry

import (
	"tm/pkg/response"
	"tm/pkg/security"

	"github.com/asaskevich/govalidator"
)

// Inquiry DTOs

// CreateInquiryForm represents the data required to create a new inquiry
type CreateInquiryForm struct {
	FullName      string `json:"full_name" valid:"required,length(2|100)" example:"John Doe"`       // Full name of the inquirer
	CompanyName   string `json:"company_name" valid:"required,length(2|100)" example:"Opplens"`     // Company name
	WorkEmail     string `json:"work_email" valid:"required,email" example:"info@opplens.com"`      // Work email address
	PhoneNumber   string `json:"phone_number" valid:"required,length(10|20)" example:"+1234567890"` // Phone number
	HCaptchaToken string `json:"hcaptcha_token" valid:"required" example:"P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."`
}

// UpdateInquiryStatusForm represents the data required to update inquiry status
type UpdateInquiryStatusForm struct {
	Status      string `json:"status" valid:"required,in(pending|reviewed|approved|rejected)" example:"reviewed"`       // New status
	Reason      string `json:"reason" valid:"required,length(5|500)" example:"Initial review completed"`                // Reason for status change
	Description string `json:"description" valid:"optional,length(0|1000)" example:"Additional notes about the review"` // Optional description
}

// SearchInquiriesForm represents search and filter parameters for inquiries
type SearchInquiriesForm struct {
	Search    *string `query:"q" valid:"optional"`                                                               // Search term for full name, company name, or email
	Status    *string `query:"status" valid:"optional,in(pending|reviewed|approved|rejected)"`                   // Filter by status
	Limit     *int    `query:"limit" valid:"optional,range(1|100)"`                                              // Limit results
	Offset    *int    `query:"offset" valid:"optional,range(0|1000000)"`                                         // Offset results
	SortBy    *string `query:"sort_by" valid:"optional,in(full_name|company_name|work_email|status|created_at)"` // Sort field
	SortOrder *string `query:"sort_order" valid:"optional,in(asc|desc)"`                                         // Sort order
}

// Response DTOs

// StatusHistoryResponse represents status history in API responses
type StatusHistoryResponse struct {
	Status      string `json:"status"`
	Reason      string `json:"reason"`
	ChangedAt   int64  `json:"changed_at"`
	Description string `json:"description"`
}

// InquiryResponse represents the inquiry data in API responses
type InquiryResponse struct {
	ID            string                  `json:"id"`
	FullName      string                  `json:"full_name"`
	CompanyName   string                  `json:"company_name"`
	WorkEmail     string                  `json:"work_email"`
	PhoneNumber   string                  `json:"phone_number"`
	Status        string                  `json:"status"`
	StatusHistory []StatusHistoryResponse `json:"status_history"`
	CreatedAt     int64                   `json:"created_at"`
	UpdatedAt     int64                   `json:"updated_at"`
}

// InquiryListResponse represents a paginated list of inquiries
type InquiryListResponse struct {
	Inquiries []*InquiryResponse `json:"inquiries"`
	Meta      *response.Meta     `json:"meta"`
}

// Helper function to convert Inquiry to InquiryResponse
func (i *Inquiry) ToResponse() *InquiryResponse {
	// Convert status history
	var statusHistoryResponses []StatusHistoryResponse
	for _, history := range i.StatusHistory {
		statusHistoryResponses = append(statusHistoryResponses, StatusHistoryResponse{
			Status:      history.Status,
			Reason:      history.Reason,
			ChangedAt:   history.ChangedAt,
			Description: history.Description,
		})
	}

	return &InquiryResponse{
		ID:            i.ID.Hex(),
		FullName:      i.FullName,
		CompanyName:   i.CompanyName,
		WorkEmail:     i.WorkEmail,
		PhoneNumber:   i.PhoneNumber,
		Status:        i.Status,
		StatusHistory: statusHistoryResponses,
		CreatedAt:     i.CreatedAt,
		UpdatedAt:     i.UpdatedAt,
	}
}

// ValidateAndSanitize validates and sanitizes the form
func (f *CreateInquiryForm) ValidateAndSanitize(xssPolicy *security.XSSPolicy) error {
	var err error

	// Sanitize and validate FullName
	f.FullName, err = xssPolicy.ValidateAndSanitizeInput(f.FullName, "text")
	if err != nil {
		return err
	}

	// Sanitize and validate CompanyName
	f.CompanyName, err = xssPolicy.ValidateAndSanitizeInput(f.CompanyName, "text")
	if err != nil {
		return err
	}

	// Sanitize and validate WorkEmail (email validation is separate)
	f.WorkEmail, err = xssPolicy.ValidateAndSanitizeInput(f.WorkEmail, "email")
	if err != nil {
		return err
	}

	// Sanitize and validate PhoneNumber
	f.PhoneNumber, err = xssPolicy.ValidateAndSanitizeInput(f.PhoneNumber, "phone")
	if err != nil {
		return err
	}

	// Standard govalidator validation
	_, err = govalidator.ValidateStruct(f)
	return err
}

// ValidateAndSanitize validates and sanitizes the status update form
func (f *UpdateInquiryStatusForm) ValidateAndSanitize(xssPolicy *security.XSSPolicy) error {
	var err error

	// Sanitize Reason
	f.Reason, err = xssPolicy.ValidateAndSanitizeInput(f.Reason, "text")
	if err != nil {
		return err
	}

	// Sanitize Description
	f.Description, err = xssPolicy.ValidateAndSanitizeInput(f.Description, "html")
	if err != nil {
		return err
	}

	// Standard govalidator validation
	_, err = govalidator.ValidateStruct(f)
	return err
}

// ValidateAndSanitize validates and sanitizes the search form
func (f *SearchInquiriesForm) ValidateAndSanitize(xssPolicy *security.XSSPolicy) error {
	if f.Search != nil {
		sanitized, err := xssPolicy.ValidateAndSanitizeInput(*f.Search, "text")
		if err != nil {
			return err
		}
		*f.Search = sanitized
	}

	// Standard govalidator validation
	_, err := govalidator.ValidateStruct(f)
	return err
}
