package control

import "context"

// Read-only observation scope, not a submission allowlist. Based on the enabled
// Org/Account SQL and Order compatibility preparation in Finance publisher
// 4a6479d6308272e05f320903e98a3ae68e4284fd. dbt's separate scope is still unbound.
const financeCRMScopeVersion = "finance-prerequisites-4a6479d-v1"

type CRMTableScope struct {
	SourceTable string   `json:"source_table"`
	FinalTable  string   `json:"final_table"`
	Role        string   `json:"role"`
	Consumers   []string `json:"consumers"`
}

func financeCRMTableScope() []CRMTableScope {
	return []CRMTableScope{
		{"Account", "nexuscrm_final.nexuscrm_account", "core", []string{"salesforce_org", "salesforce_account", "salesforce_order"}},
		{"Org__c", "nexuscrm_final.nexuscrm_org_c", "core", []string{"salesforce_org", "salesforce_account"}},
		{"Order", "nexuscrm_final.nexuscrm_order", "core", []string{"salesforce_order", "salesforce_account"}},
		{"OrderItem", "nexuscrm_final.nexuscrm_orderitem", "core", []string{"salesforce_order"}},
		{"User", "nexuscrm_final.nexuscrm_user", "reference", []string{"salesforce_org", "salesforce_account"}},
		{"RecordType", "nexuscrm_final.nexuscrm_recordtype", "reference", []string{"salesforce_account"}},
		{"Product2", "nexuscrm_final.nexuscrm_product2", "reference", []string{"salesforce_order"}},
		{"Quote", "nexuscrm_final.nexuscrm_quote", "reference", []string{"salesforce_order"}},
		{"Opportunity", "nexuscrm_final.nexuscrm_opportunity", "reference", []string{"salesforce_order"}},
	}
}

func financeCRMTables(source bool) []string {
	items := []string{}
	for _, table := range financeCRMTableScope() {
		if source {
			items = append(items, table.SourceTable)
		} else {
			items = append(items, table.FinalTable)
		}
	}
	return items
}

// A scope expansion must backfill references that predate the old four-table
// cursor. Existing runs remain in the store; replay uses their stable identity.
func crmScopeCheckpoint(previous CollectionState) CollectionState {
	if previous.ScopeVersion != financeCRMScopeVersion {
		return CollectionState{}
	}
	return previous
}

type CRMTableView struct {
	CRMTableScope
	LatestRun *ProviderRun `json:"latest_run,omitempty"`
	Status    string       `json:"status"`
	Message   string       `json:"message"`
}

func (o *Operations) crmTableViews(ctx context.Context) ([]CRMTableView, error) {
	views := []CRMTableView{}
	for _, scope := range financeCRMTableScope() {
		v := CRMTableView{CRMTableScope: scope, Status: "unknown", Message: "未观察到此表加载；不推断数据就绪"}
		runs, err := o.Runs(ctx, RunFilter{Provider: "crm_load", Task: "crm_load", OutputRef: scope.FinalTable, Limit: 1})
		if err != nil {
			return nil, err
		}
		if len(runs) != 0 {
			v.LatestRun = &runs[0]
			v.Status = runs[0].Status
			v.Message = "逐表加载审计；新鲜度与财务验收未通过此状态推断"
		}
		views = append(views, v)
	}
	return views, nil
}

// A job without proven manifest/table scope is diagnostic, never the latest
// execution of the finance subset. Preserve its original status and timestamp.
func separateCRMExtractDiagnostic(view *OperationTaskView) {
	if view.Key == "crm_extract" {
		view.LatestJobRun, view.LatestRun = view.LatestRun, nil
	}
}
