package model

import (
	"time"

	"gorm.io/datatypes"
)

type RentalOrder struct {
	ID                        uint64         `gorm:"primaryKey" json:"id"`
	OrderNo                   string         `gorm:"size:64;not null;uniqueIndex" json:"order_no"`
	ListingID                 uint64         `gorm:"not null;index" json:"listing_id"`
	AccountID                 uint64         `gorm:"not null;index" json:"account_id"`
	OwnerID                   uint64         `gorm:"not null;index" json:"owner_id"`
	RenterID                  uint64         `gorm:"not null;index" json:"renter_id"`
	RentedAt                  *time.Time     `json:"rented_at"`
	HandoffStartedAt          *time.Time     `json:"handoff_started_at"`
	EstimatedDurationHours    int            `gorm:"not null;default:24" json:"estimated_duration_hours"`
	RentAmountCent            int64          `gorm:"not null;default:0" json:"-"`
	OwnerRentAmountCent       int64          `gorm:"not null;default:0" json:"-"`
	DepositAmountCent         int64          `gorm:"not null;default:0" json:"-"`
	DepositOriginalAmountCent int64          `gorm:"not null;default:0" json:"-"`
	DepositWaivedAmountCent   int64          `gorm:"not null;default:0" json:"-"`
	PlatformFeeCent           int64          `gorm:"not null;default:0" json:"-"`
	AccountSnapshot           datatypes.JSON `json:"account_snapshot"`
	Status                    string         `gorm:"size:32;not null;default:'pending_payment'" json:"status"`
	HandoffStatus             string         `gorm:"size:32;not null;default:'none'" json:"handoff_status"`
	SettlementStatus          string         `gorm:"size:32;not null;default:'unsettled'" json:"settlement_status"`
	RefundStatus              string         `gorm:"size:32;not null;default:'none';index" json:"refund_status"`
	RefundAmountCent          int64          `gorm:"not null;default:0" json:"refund_amount_cent"`
	RefundedAt                *time.Time     `json:"refunded_at"`
	DepositHoldStatus         string         `gorm:"size:16;not null;default:'none';index" json:"deposit_hold_status"`
	DepositHoldAmountCent     int64          `gorm:"not null;default:0" json:"deposit_hold_amount_cent"`
	DepositHoldReason         string         `gorm:"size:255;not null;default:''" json:"deposit_hold_reason"`
	DepositHeldBy             *uint64        `json:"deposit_held_by"`
	DepositHeldAt             *time.Time     `json:"deposit_held_at"`
	DepositHoldReleasedAt     *time.Time     `json:"deposit_hold_released_at"`
	OwnerSettledAt            *time.Time     `json:"owner_settled_at"`
	SettledAt                 *time.Time     `json:"settled_at"`
	CreatedAt                 time.Time      `json:"created_at"`
	UpdatedAt                 time.Time      `json:"updated_at"`
}

func (RentalOrder) TableName() string {
	return "rental_orders"
}

// 押金暂扣状态：客服可对进行中订单的押金退款进行暂扣，订单照常结算，
// 但本应原路退给租客的押金部分挂起不退，后续由客服手动归还。
const (
	DepositHoldStatusNone     = "none"     // 未暂扣
	DepositHoldStatusHeld     = "held"     // 已暂扣（押金退款被拦截/挂起）
	DepositHoldStatusReleased = "released" // 已归还
)

// IsDepositHeld 判断订单当前是否处于押金暂扣状态。
func (o *RentalOrder) IsDepositHeld() bool {
	return o.DepositHoldStatus == DepositHoldStatusHeld
}

// ApplyDepositHold 在任一结算退款路径中拦截押金退款。
// totalRefundCent 是本次本应原路退还给租客的总金额（含租金退款和押金退款），
// depositPortionCent 是其中属于押金退款的部分。
// 若订单已暂扣，则把押金部分（不超过本次退款总额）从退款中扣除，
// 并把尚未记录过的部分累加到暂扣金额（累计不超过实付押金），返回扣除后实际发起原路退款的金额；
// 未暂扣时原样返回 totalRefundCent。
// 注意：本函数只做“少退、挂起”，绝不多退，因此在任何路径下都不会造成租客损失或平台多付。
func (o *RentalOrder) ApplyDepositHold(totalRefundCent, depositPortionCent int64) int64 {
	if !o.IsDepositHeld() {
		return totalRefundCent
	}
	withheld := depositPortionCent
	if withheld > totalRefundCent {
		withheld = totalRefundCent
	}
	if withheld <= 0 {
		return totalRefundCent
	}
	remainingDepositHoldCent := o.DepositAmountCent - o.DepositHoldAmountCent
	if remainingDepositHoldCent > 0 {
		newHold := withheld
		if newHold > remainingDepositHoldCent {
			newHold = remainingDepositHoldCent
		}
		o.DepositHoldAmountCent += newHold
	}
	return totalRefundCent - withheld
}
