// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
// SPDX-License-Identifier: GPL-3.0-or-later

package v1_27

import (
	"xorm.io/xorm"
)

// AddLicensingTables creates the license, license_entitlement, license_activation,
// and product_tier tables for the consumer-facing DLID licensing system (#617).
func AddLicensingTables(x *xorm.Engine) error {
	type License struct {
		ID         int64  `xorm:"pk autoincr"`
		UserID     int64  `xorm:"INDEX NOT NULL"`
		DLID       string `xorm:"VARCHAR(36) UNIQUE NOT NULL"`
		Tier       string `xorm:"VARCHAR(30) NOT NULL DEFAULT 'base'"`
		MaxDomains int    `xorm:"NOT NULL DEFAULT 1"`
		Status     string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'active'"`
		ExpiresAt  int64  `xorm:"INDEX"`
		Notes      string `xorm:"TEXT"`
		CreatedAt  int64  `xorm:"INDEX CREATED"`
		UpdatedAt  int64  `xorm:"UPDATED"`
	}

	type LicenseEntitlement struct {
		ID          int64  `xorm:"pk autoincr"`
		LicenseID   int64  `xorm:"INDEX NOT NULL"`
		ProductCode string `xorm:"VARCHAR(30) NOT NULL"`
		RepoOwner   string `xorm:"VARCHAR(100) NOT NULL DEFAULT 'MokoConsulting'"`
		RepoName    string `xorm:"VARCHAR(100) NOT NULL"`
		IsCustom    bool   `xorm:"NOT NULL DEFAULT false"`
		CreatedAt   int64  `xorm:"CREATED"`
	}

	type LicenseActivation struct {
		ID          int64  `xorm:"pk autoincr"`
		LicenseID   int64  `xorm:"INDEX NOT NULL"`
		Domain      string `xorm:"VARCHAR(255) NOT NULL"`
		IPAddress   string `xorm:"VARCHAR(64)"`
		JoomlaVer   string `xorm:"VARCHAR(20)"`
		ActivatedAt int64  `xorm:"CREATED"`
		LastSeenAt  int64
	}

	type ProductTier struct {
		ID         int64  `xorm:"pk autoincr"`
		TierKey    string `xorm:"VARCHAR(30) UNIQUE NOT NULL"`
		TierName   string `xorm:"VARCHAR(100) NOT NULL"`
		Repos      string `xorm:"TEXT"`
		MaxDomains int    `xorm:"NOT NULL DEFAULT 1"`
		SortOrder  int    `xorm:"NOT NULL DEFAULT 0"`
	}

	type LicenseAuditLog struct {
		ID        int64  `xorm:"pk autoincr"`
		LicenseID int64  `xorm:"INDEX NOT NULL"`
		Action    string `xorm:"VARCHAR(50) NOT NULL"`
		OldValue  string `xorm:"VARCHAR(100)"`
		NewValue  string `xorm:"VARCHAR(100)"`
		CreatedAt int64  `xorm:"INDEX CREATED"`
	}

	if err := x.Sync(new(License), new(LicenseEntitlement), new(LicenseActivation), new(ProductTier), new(LicenseAuditLog)); err != nil {
		return err
	}

	// Add composite unique indexes
	if _, err := x.Exec("CREATE UNIQUE INDEX IF NOT EXISTS UQE_license_entitlement_lic_prod ON license_entitlement (license_id, product_code)"); err != nil {
		// MySQL doesn't support IF NOT EXISTS for indexes — try without
		x.Exec("CREATE UNIQUE INDEX UQE_license_entitlement_lic_prod ON license_entitlement (license_id, product_code)")
	}
	if _, err := x.Exec("CREATE UNIQUE INDEX IF NOT EXISTS UQE_license_activation_lic_domain ON license_activation (license_id, domain)"); err != nil {
		x.Exec("CREATE UNIQUE INDEX UQE_license_activation_lic_domain ON license_activation (license_id, domain)")
	}

	// Seed product tiers
	tiers := []ProductTier{
		{TierKey: "base", TierName: "MokoSuite Base", Repos: `["MokoSuite"]`, MaxDomains: 1, SortOrder: 0},
		{TierKey: "crm", TierName: "MokoSuite CRM", Repos: `["MokoSuite","MokoSuiteCRM"]`, MaxDomains: 3, SortOrder: 10},
		{TierKey: "erp", TierName: "MokoSuite ERP", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP"]`, MaxDomains: 3, SortOrder: 20},
		{TierKey: "child", TierName: "MokoSuite Child", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteChild"]`, MaxDomains: 3, SortOrder: 25},
		{TierKey: "create", TierName: "MokoSuite Create", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteCreate"]`, MaxDomains: 3, SortOrder: 26},
		{TierKey: "npo", TierName: "MokoSuite NPO", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteNPO"]`, MaxDomains: 3, SortOrder: 27},
		{TierKey: "hrm", TierName: "MokoSuite HRM", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteHRM"]`, MaxDomains: 3, SortOrder: 30},
		{TierKey: "mrp", TierName: "MokoSuite MRP", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuiteMRP"]`, MaxDomains: 3, SortOrder: 35},
		{TierKey: "pos", TierName: "MokoSuite POS", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuitePOS"]`, MaxDomains: 5, SortOrder: 40},
		{TierKey: "shop", TierName: "MokoSuite Shop", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuiteShop"]`, MaxDomains: 5, SortOrder: 45},
		{TierKey: "restaurant", TierName: "MokoSuite Restaurant", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuitePOS","MokoSuiteRestaurant"]`, MaxDomains: 5, SortOrder: 50},
		{TierKey: "suite", TierName: "MokoSuite Suite", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuitePOS","MokoSuiteShop","MokoSuiteHRM","MokoSuiteMRP","MokoSuiteChild","MokoSuiteCreate","MokoSuiteNPO","MokoSuiteRestaurant","MokoSuiteForms"]`, MaxDomains: 10, SortOrder: 90},
		{TierKey: "enterprise", TierName: "MokoSuite Enterprise", Repos: `["MokoSuite","MokoSuiteCRM","MokoSuiteERP","MokoSuitePOS","MokoSuiteShop","MokoSuiteHRM","MokoSuiteMRP","MokoSuiteChild","MokoSuiteCreate","MokoSuiteNPO","MokoSuiteRestaurant","MokoSuiteForms","MokoSuiteCommunity","MokoSuiteBackup","MokoSuiteStoreLocator","MokoSuiteOpenGraph","MokoSuiteCross"]`, MaxDomains: 0, SortOrder: 100},
	}

	for _, t := range tiers {
		// Only insert if the tier doesn't already exist
		count, err := x.Where("tier_key = ?", t.TierKey).Count(new(ProductTier))
		if err != nil {
			return err
		}
		if count == 0 {
			if _, err := x.Insert(&t); err != nil {
				return err
			}
		}
	}

	return nil
}
