package migration

import (
	"log"

	"gorm.io/gorm"
)

type TableRenameStep struct {
	OldName string
	NewName string
}

var TableRenameSteps = []TableRenameStep{
	{OldName: "laporan_harian", NewName: "daily_reports"},
	{OldName: "document_sequences", NewName: "serial_sequences"},
	{OldName: "status_po", NewName: "po_status"},
	{OldName: "po_status", NewName: "operational_records"},
	{OldName: "documents", NewName: "operational_records"},
	{OldName: "profil_pelanggan", NewName: "customer_profiles"},
	{OldName: "riwayat_aktivitas", NewName: "activity_logs"},
	{OldName: "ioms", NewName: "memorandums"},
	{OldName: "service_job_requests", NewName: "service_authorizations"},
}

var ColumnRenameMapping = map[string]map[string]string{
	"operational_records": {
		"document_status": "record_status",
	},
	"activity_logs": {
		"aksi":       "action",
		"keterangan": "details",
	},
	"service_requisitions": {
		"spjb_no": "sales_agreement_no",
	},
	"service_job_requests": {
		"tipe_permintaan": "request_type",
		"nama_pekerjaan":  "job_name",
		"komponen":        "component",
	},
	"service_authorizations": {
		"tipe_permintaan": "request_type",
		"nama_pekerjaan":  "job_name",
		"komponen":        "component",
	},
}

var requestTypeMappings = map[string]string{
	"perbaikan": "repair",
	"kalibrasi": "calibration",
	"garansi":   "repair",
	"warranty":  "repair",
}

var statusMappings = map[string]string{
	"konsep":        "draft",
	"draft":         "draft",
	"completed":     "submitted",
	"submitted":     "submitted",
	"terverifikasi": "verified",
	"verified":      "approved",
	"disetujui":     "approved",
	"ditolak":       "rejected",
	"terkunci":      "locked",
}

var recordStatusMappings = map[string]string{
	"konsep":        "DRAFT",
	"draft":         "DRAFT",
	"completed":     "OUTSTANDING",
	"submitted":     "OUTSTANDING",
	"terverifikasi": "VERIFIED",
	"verified":      "VERIFIED",
	"disetujui":     "VERIFIED",
	"approved":      "VERIFIED",
	"ditolak":       "CANCELLED",
	"rejected":      "CANCELLED",
	"terkunci":      "LOCKED",
	"locked":        "LOCKED",
	"dibatalkan":    "CANCELLED",
	"cancelled":     "CANCELLED",
}

// ApplyLegacyTransforms normalizes historical table, column, and literal values.
// It is used by both runtime bootstrap and the one-off migration command.
func ApplyLegacyTransforms(db *gorm.DB) {
	if db == nil {
		return
	}

	log.Println("🔄 Memulai legacy schema/data transforms...")
	applyTableRenames(db, TableRenameSteps)
	applyColumnRenames(db, ColumnRenameMapping)
	applyColumnValueMappings(db, []columnValueMapping{
		{tableName: "service_job_requests", columnName: "request_type", mappings: requestTypeMappings},
		{tableName: "service_authorizations", columnName: "request_type", mappings: requestTypeMappings},
		{tableName: "service_requisitions", columnName: "status", mappings: statusMappings},
		{tableName: "service_job_requests", columnName: "status", mappings: statusMappings},
		{tableName: "service_authorizations", columnName: "status", mappings: statusMappings},
		{tableName: "ioms", columnName: "status", mappings: statusMappings},
		{tableName: "memorandums", columnName: "status", mappings: statusMappings},
		{tableName: "credit_limits", columnName: "status", mappings: statusMappings},
		{tableName: "customer_profiles", columnName: "status", mappings: statusMappings},
		{tableName: "operational_records", columnName: "record_status", mappings: recordStatusMappings},
	})
	log.Println("✅ Legacy schema/data transforms selesai.")
}

type columnValueMapping struct {
	tableName  string
	columnName string
	mappings   map[string]string
}

func applyTableRenames(db *gorm.DB, steps []TableRenameStep) {
	migrator := db.Migrator()
	for _, step := range steps {
		if !migrator.HasTable(step.OldName) {
			continue
		}
		if migrator.HasTable(step.NewName) {
			log.Printf("ℹ️ Tabel target '%s' sudah ada. Lewati rename dari '%s'.", step.NewName, step.OldName)
			continue
		}
		if err := migrator.RenameTable(step.OldName, step.NewName); err != nil {
			log.Printf("❌ Gagal merename tabel '%s' ke '%s': %v", step.OldName, step.NewName, err)
			continue
		}
		log.Printf("✅ Berhasil merename tabel '%s' menjadi '%s'", step.OldName, step.NewName)
	}
}

func applyColumnRenames(db *gorm.DB, mappings map[string]map[string]string) {
	migrator := db.Migrator()
	for tableName, cols := range mappings {
		if !migrator.HasTable(tableName) {
			continue
		}
		for oldColumn, newColumn := range cols {
			if !migrator.HasColumn(tableName, oldColumn) {
				continue
			}
			if err := migrator.RenameColumn(tableName, oldColumn, newColumn); err != nil {
				log.Printf("❌ Gagal merename kolom '%s' ke '%s' di tabel '%s': %v", oldColumn, newColumn, tableName, err)
				continue
			}
			log.Printf("✅ Berhasil merename kolom '%s' menjadi '%s' di tabel '%s'", oldColumn, newColumn, tableName)
		}
	}
}

func applyColumnValueMappings(db *gorm.DB, mappings []columnValueMapping) {
	for _, item := range mappings {
		updateColumnValues(db, item.tableName, item.columnName, item.mappings)
	}
}

func updateColumnValues(db *gorm.DB, tableName, columnName string, mappings map[string]string) {
	migrator := db.Migrator()
	if !migrator.HasTable(tableName) || !migrator.HasColumn(tableName, columnName) {
		return
	}

	for oldValue, newValue := range mappings {
		if err := db.Exec("UPDATE "+tableName+" SET "+columnName+" = ? WHERE "+columnName+" = ?", newValue, oldValue).Error; err != nil {
			log.Printf("❌ Gagal menormalkan data %s.%s: %v", tableName, columnName, err)
		}
	}

	log.Printf("✅ Data %s.%s normalized.", tableName, columnName)
}
