package catalogapp

import (
	"context"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"slices"
	"sort"

	consumerv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/catalog/consumerv1"
	"github.com/pingcap-inc/nexuscrm-controlplane/internal/catalogconsumerauthority"
)

func canonicalEffectiveMetadataComponents(
	values []EffectiveMetadataComponent,
	capabilityName string,
) ([]EffectiveMetadataComponent, error) {
	result := make([]EffectiveMetadataComponent, len(values))
	for index, value := range values {
		result[index] = EffectiveMetadataComponent{
			ComponentKind:          value.ComponentKind,
			ComponentFormatVersion: value.ComponentFormatVersion,
			BusinessKey:            value.BusinessKey,
			ContentDigest:          value.ContentDigest,
			CanonicalBehavior:      append([]byte(nil), value.CanonicalBehavior...),
		}
		if err := consumerv1.ValidateEffectiveMetadataComponentForCapability(
			result[index], capabilityName,
		); err != nil {
			return nil, fmt.Errorf(
				"effective metadata component[%d] kind %q key %q is invalid: %w",
				index, result[index].ComponentKind, result[index].BusinessKey, err,
			)
		}
	}
	sort.Slice(result, func(left, right int) bool {
		return effectiveMetadataComponentKey(result[left]) <
			effectiveMetadataComponentKey(result[right])
	})
	for index := 1; index < len(result); index++ {
		if effectiveMetadataComponentKey(result[index-1]) ==
			effectiveMetadataComponentKey(result[index]) {
			return nil, fmt.Errorf(
				"effective metadata components contain a duplicate identity",
			)
		}
	}
	return result, nil
}

func effectiveMetadataComponentKey(value EffectiveMetadataComponent) string {
	return value.ComponentKind + "\x00" + value.BusinessKey
}

func validateRequiredEffectiveMetadataComponents(
	values []EffectiveMetadataComponent,
	capabilityName string,
) error {
	return validateRequiredEffectiveMetadataComponentsForObjectSearchFormats(
		values, capabilityName, true,
	)
}

func validateCurrentRequiredEffectiveMetadataComponents(
	values []EffectiveMetadataComponent,
	capabilityName string,
) error {
	return validateRequiredEffectiveMetadataComponentsForObjectSearchFormats(
		values, capabilityName, false,
	)
}

func validateRequiredEffectiveMetadataComponentsForObjectSearchFormats(
	values []EffectiveMetadataComponent,
	capabilityName string,
	allowHistoricalObjectSearch bool,
) error {
	hasApplicationNavigation := false
	hasObjectSearch := false
	for _, value := range values {
		switch {
		case value.ComponentKind == consumerv1.EffectiveApplicationNavigationComponentKind &&
			value.BusinessKey == consumerv1.EffectiveApplicationNavigationComponentBusinessKey &&
			value.ComponentFormatVersion == 1:
			hasApplicationNavigation = true
			continue
		case value.ComponentKind == consumerv1.EffectiveObjectSearchComponentKind &&
			value.BusinessKey == consumerv1.EffectiveObjectSearchComponentBusinessKey &&
			objectSearchFormatAccepted(
				value.ComponentFormatVersion,
				capabilityName,
				allowHistoricalObjectSearch,
			):
			hasObjectSearch = true
			continue
		}
		if value.ComponentFormatVersion != 1 {
			return fmt.Errorf(
				"%w: complete App metadata contains an unsupported effective component",
				ErrNotReady,
			)
		}
		switch value.ComponentKind {
		case consumerv1.EffectiveStandardFlowComponentKind:
			if _, err := consumerv1.DecodeEffectiveStandardFlowDocument(
				value.CanonicalBehavior,
			); err != nil {
				return fmt.Errorf("%w: invalid effective standard Flow component", ErrNotReady)
			}
		case consumerv1.EffectivePageLayoutComponentKind:
			if capabilityName != consumerv1.AppMetadataV3CapabilityName ||
				len(value.CanonicalBehavior) == 0 ||
				value.CanonicalBehavior[0] != '{' ||
				!json.Valid(value.CanonicalBehavior) {
				return fmt.Errorf("%w: invalid effective page-layout component", ErrNotReady)
			}
		case consumerv1.EffectiveStandardActionComponentKind:
			if capabilityName != consumerv1.AppMetadataV3CapabilityName ||
				len(value.CanonicalBehavior) == 0 ||
				value.CanonicalBehavior[0] != '[' ||
				!json.Valid(value.CanonicalBehavior) {
				return fmt.Errorf("%w: invalid effective standard-action component", ErrNotReady)
			}
		default:
			// V3 effective components are deliberately opaque and extensible.
			// Their common envelope was already validated above; Catalog must not
			// turn their lexical sort position or an internal closed allowlist into
			// an accidental wire contract. V2 retains its original closed shape.
			if capabilityName != consumerv1.AppMetadataV3CapabilityName {
				return fmt.Errorf(
					"%w: complete App metadata contains an unsupported effective component",
					ErrNotReady,
				)
			}
		}
	}
	if !hasApplicationNavigation || !hasObjectSearch {
		return fmt.Errorf(
			"%w: complete App metadata requires the effective application-navigation and object-search components",
			ErrNotReady,
		)
	}
	return nil
}

func objectSearchFormatAccepted(
	format uint32,
	capabilityName string,
	allowHistorical bool,
) bool {
	switch capabilityName {
	case consumerv1.AppMetadataV2CapabilityName:
		return format == effectiveObjectSearchFormatV2 ||
			(allowHistorical && format == 1)
	case consumerv1.AppMetadataV3CapabilityName:
		return format == effectiveObjectSearchFormatV6 ||
			(allowHistorical &&
				(format == 1 || format == effectiveObjectSearchFormatV2 ||
					format == effectiveObjectSearchFormatV3 ||
					format == effectiveObjectSearchFormatV4 ||
					format == effectiveObjectSearchFormatV5))
	default:
		return false
	}
}

const (
	effectiveObjectSearchFormatV2 uint32 = 2
	effectiveObjectSearchFormatV3 uint32 = 3
	effectiveObjectSearchFormatV4 uint32 = 4
	effectiveObjectSearchFormatV5 uint32 = 5
	effectiveObjectSearchFormatV6 uint32 = 6
)

func ComputeEffectiveMetadataSetDigest(
	values []EffectiveMetadataComponent,
) (string, error) {
	return catalogconsumerauthority.ComputeEffectiveMetadataSetDigest(values)
}

func operationEffectiveMetadataCapabilityTx(
	ctx context.Context,
	tx *sql.Tx,
	operation Operation,
) (string, error) {
	grants, err := readOperationConsumerGrantsTx(ctx, tx, operation)
	if err != nil {
		return "", err
	}
	capabilityName, err := effectiveMetadataCapabilityForConsumerGrants(grants)
	if err != nil {
		return "", fmt.Errorf(
			"%w: operation consumer grants mix App metadata capability versions: %v",
			ErrCorrupt,
			err,
		)
	}
	return capabilityName, nil
}

func commitEffectiveMetadataSetTx(
	ctx context.Context,
	tx *sql.Tx,
	operation Operation,
	catalogSnapshotDigest string,
	values []EffectiveMetadataComponent,
) error {
	capabilityName, err := operationEffectiveMetadataCapabilityTx(ctx, tx, operation)
	if err != nil {
		return err
	}
	if capabilityName == "" {
		if len(values) != 0 {
			return fmt.Errorf(
				"%w: effective metadata was supplied without a complete App metadata consumer grant",
				ErrConflict,
			)
		}
		return nil
	}
	canonical, err := canonicalEffectiveMetadataComponents(values, capabilityName)
	if err != nil {
		return err
	}
	if err := validateCurrentRequiredEffectiveMetadataComponents(canonical, capabilityName); err != nil {
		return err
	}
	setDigest, err := ComputeEffectiveMetadataSetDigest(canonical)
	if err != nil {
		return err
	}
	for _, value := range canonical {
		componentID := hashKey(
			"catalog-effective-metadata-component", operation.OperationID,
			value.ComponentKind, value.BusinessKey,
		)
		_, err = tx.ExecContext(ctx, `INSERT INTO _System_CatalogEffectiveMetadataComponent
(EffectiveMetadataComponentId, OperationId, OrgId, AppInstallationId,
ComponentKind, ComponentFormatVersion, BusinessKey, ContentDigest,
CanonicalBehavior, CreatedDate)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP(6))`,
			componentID, operation.OperationID, operation.OrgID,
			operation.AppInstallationID, value.ComponentKind,
			epochText(uint64(value.ComponentFormatVersion)), value.BusinessKey,
			value.ContentDigest, value.CanonicalBehavior,
		)
		if isDuplicate(err) {
			return ErrConflict
		}
		if err != nil {
			return err
		}
	}
	_, err = tx.ExecContext(ctx, `INSERT INTO _System_CatalogEffectiveMetadataSet
(OperationId, OrgId, AppInstallationId, CatalogSnapshotDigest,
ComponentSetDigest, ComponentCount, CreatedDate)
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP(6))`,
		operation.OperationID, operation.OrgID, operation.AppInstallationID,
		catalogSnapshotDigest, setDigest, epochText(uint64(len(canonical))),
	)
	if isDuplicate(err) {
		return ErrConflict
	}
	return err
}

func verifyEffectiveMetadataSetTx(
	ctx context.Context,
	tx *sql.Tx,
	operation Operation,
	catalogSnapshotDigest string,
	expected []EffectiveMetadataComponent,
) error {
	capabilityName, err := operationEffectiveMetadataCapabilityTx(ctx, tx, operation)
	if err != nil {
		return err
	}
	if capabilityName == "" {
		return fmt.Errorf("%w: operation has no complete App metadata consumer grant", ErrConflict)
	}
	canonical, err := canonicalEffectiveMetadataComponents(expected, capabilityName)
	if err != nil {
		return err
	}
	var (
		orgID             string
		appInstallationID string
		snapshotDigest    string
		setDigest         string
		rawCount          []byte
	)
	err = tx.QueryRowContext(ctx, `SELECT
OrgId, AppInstallationId, CatalogSnapshotDigest, ComponentSetDigest,
ComponentCount
FROM _System_CatalogEffectiveMetadataSet
WHERE OperationId = ?
FOR UPDATE`, operation.OperationID).Scan(
		&orgID, &appInstallationID, &snapshotDigest, &setDigest, &rawCount,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return fmt.Errorf(
			"%w: operation has no effective metadata commitment",
			ErrConflict,
		)
	}
	if err != nil {
		return err
	}
	count, err := parseEpochAllowZero(rawCount)
	if err != nil {
		return err
	}
	rows, err := tx.QueryContext(ctx, `SELECT
ComponentKind, ComponentFormatVersion, BusinessKey, ContentDigest,
CanonicalBehavior, OrgId, AppInstallationId
FROM _System_CatalogEffectiveMetadataComponent
WHERE OperationId = ?
ORDER BY BINARY ComponentKind, BINARY BusinessKey
FOR UPDATE`, operation.OperationID)
	if err != nil {
		return err
	}
	defer rows.Close()
	var stored []EffectiveMetadataComponent
	for rows.Next() {
		var (
			value           EffectiveMetadataComponent
			rawVersion      []byte
			rowOrgID        string
			rowInstallation string
		)
		if err := rows.Scan(
			&value.ComponentKind, &rawVersion, &value.BusinessKey,
			&value.ContentDigest, &value.CanonicalBehavior,
			&rowOrgID, &rowInstallation,
		); err != nil {
			return err
		}
		version, err := parseEpoch(rawVersion)
		if err != nil || version > uint64(^uint32(0)) {
			return fmt.Errorf("%w: invalid effective metadata component version", ErrCorrupt)
		}
		value.ComponentFormatVersion = uint32(version)
		if rowOrgID != operation.OrgID ||
			rowInstallation != operation.AppInstallationID {
			return fmt.Errorf(
				"%w: effective metadata component scope changed",
				ErrConflict,
			)
		}
		stored = append(stored, value)
	}
	if err := rows.Err(); err != nil {
		return err
	}
	storedCanonical, err := canonicalEffectiveMetadataComponents(stored, capabilityName)
	if err != nil || !slices.EqualFunc(
		storedCanonical, stored,
		func(left, right EffectiveMetadataComponent) bool {
			return left.ComponentKind == right.ComponentKind &&
				left.ComponentFormatVersion == right.ComponentFormatVersion &&
				left.BusinessKey == right.BusinessKey &&
				left.ContentDigest == right.ContentDigest &&
				slices.Equal(left.CanonicalBehavior, right.CanonicalBehavior)
		},
	) {
		return fmt.Errorf("%w: effective metadata component set is invalid", ErrCorrupt)
	}
	if err := validateRequiredEffectiveMetadataComponents(stored, capabilityName); err != nil {
		return err
	}
	currentDigest, err := ComputeEffectiveMetadataSetDigest(stored)
	if err != nil {
		return err
	}
	if orgID != operation.OrgID ||
		appInstallationID != operation.AppInstallationID ||
		snapshotDigest != catalogSnapshotDigest ||
		count != uint64(len(stored)) ||
		setDigest != currentDigest {
		return fmt.Errorf(
			"%w: effective metadata set disagrees with its Catalog snapshot",
			ErrConflict,
		)
	}
	if expected != nil && !slices.EqualFunc(
		stored, canonical,
		func(left, right EffectiveMetadataComponent) bool {
			return left.ComponentKind == right.ComponentKind &&
				left.ComponentFormatVersion == right.ComponentFormatVersion &&
				left.BusinessKey == right.BusinessKey &&
				left.ContentDigest == right.ContentDigest &&
				slices.Equal(left.CanonicalBehavior, right.CanonicalBehavior)
		},
	) {
		return fmt.Errorf(
			"%w: effective metadata differs from the exact retry",
			ErrConflict,
		)
	}
	return nil
}

// verifyConsumerMetadataSelectionTx fences every consumer before serving can
// advance beyond the step where its immutable snapshot can still be selected.
func verifyConsumerMetadataSelectionTx(
	ctx context.Context,
	tx *sql.Tx,
	operation Operation,
) error {
	grants, err := readOperationConsumerGrantsTx(ctx, tx, operation)
	if err != nil {
		return err
	}
	if len(grants) == 0 {
		return nil
	}
	snapshotDigest, err := readOperationMetadataSelection(ctx, tx, operation.OperationID, true)
	if errors.Is(err, ErrNotFound) {
		return fmt.Errorf("%w: consumer operation requires a committed metadata selection before serving", ErrNotReady)
	}
	if err != nil {
		return err
	}
	capabilityName, err := effectiveMetadataCapabilityForConsumerGrants(grants)
	if err != nil {
		return fmt.Errorf("%w: operation consumer grants mix App metadata capability versions: %v", ErrCorrupt, err)
	}
	if capabilityName == "" {
		return nil
	}
	var present int
	err = tx.QueryRowContext(ctx, `SELECT 1
FROM _System_CatalogEffectiveMetadataSet
WHERE OperationId = ?
FOR UPDATE`, operation.OperationID).Scan(&present)
	if errors.Is(err, sql.ErrNoRows) {
		return fmt.Errorf(
			"%w: complete App metadata consumer operation has no effective metadata commitment",
			ErrNotReady,
		)
	}
	if err != nil {
		return err
	}
	return verifyEffectiveMetadataSetTx(
		ctx, tx, operation, snapshotDigest, nil,
	)
}
