package models

import (
	"time"

	"golang.org/x/crypto/bcrypt"
)

// User represents a user account
type User struct {
	ID           uint       `json:"id" gorm:"primaryKey;autoIncrement"`
	Username     string     `json:"username" gorm:"uniqueIndex;not null;size:50"`
	Email        string     `json:"email" gorm:"uniqueIndex;not null;size:255"`
	Password     string     `json:"-" gorm:"-"` // Only used for input, never stored
	PasswordHash string     `json:"-" gorm:"column:password_hash;not null"`
	BaseCurrency string     `json:"base_currency" gorm:"not null;default:EUR;size:3"`
	FuelStops    []FuelStop `json:"fuel_stops,omitempty" gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
	Vehicles     []Vehicle  `json:"vehicles,omitempty" gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
	CreatedAt    time.Time  `json:"created_at" gorm:"autoCreateTime"`
	UpdatedAt    time.Time  `json:"updated_at" gorm:"autoUpdateTime"`
}

// CheckPassword verifies a password against the stored hash
func (u *User) CheckPassword(password string) bool {
	// Defensive programming - check for nil user
	if u == nil {
		return false
	}

	// Check for empty password or password hash
	if password == "" || u.PasswordHash == "" {
		return false
	}

	err := bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password))
	return err == nil
}

// Vehicle represents a user's vehicle
type Vehicle struct {
	ID           uint       `json:"id" gorm:"primaryKey;autoIncrement"`
	UserID       uint       `json:"user_id" gorm:"not null;index"`
	User         User       `json:"-" gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
	Name         string     `json:"name" gorm:"not null;size:100"`
	Make         string     `json:"make" gorm:"size:50"`
	Model        string     `json:"model" gorm:"size:50"`
	Year         int        `json:"year" gorm:"default:0"`
	LicensePlate string     `json:"license_plate" gorm:"size:20"`
	FuelType     string     `json:"fuel_type" gorm:"size:50"`
	Notes        string     `json:"notes" gorm:"type:text"`
	IsActive     bool       `json:"is_active" gorm:"default:true"`
	FuelStops    []FuelStop `json:"fuel_stops,omitempty" gorm:"foreignKey:VehicleID;constraint:OnDelete:CASCADE"`
	CreatedAt    time.Time  `json:"created_at" gorm:"autoCreateTime"`
	UpdatedAt    time.Time  `json:"updated_at" gorm:"autoUpdateTime"`
}

// FuelStop represents a fuel station stop record
type FuelStop struct {
	ID          uint      `json:"id" gorm:"primaryKey;autoIncrement"`
	UserID      uint      `json:"user_id" gorm:"not null;index"`
	User        User      `json:"-" gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
	VehicleID   uint      `json:"vehicle_id" gorm:"not null;index"`
	Vehicle     Vehicle   `json:"vehicle,omitempty" gorm:"foreignKey:VehicleID;constraint:OnDelete:CASCADE"`
	Date        time.Time `json:"date" gorm:"not null;type:date"`
	StationName string    `json:"station_name" gorm:"not null;size:100"`
	Location    string    `json:"location" gorm:"not null;size:255"`
	FuelType    string    `json:"fuel_type" gorm:"not null;size:50"`
	Liters      float64   `json:"liters" gorm:"not null;type:decimal(10,3)"`
	PricePerL   float64   `json:"price_per_l" gorm:"not null;type:decimal(10,4)"`
	TotalPrice  float64   `json:"total_price" gorm:"not null;type:decimal(10,2)"`
	Currency    string    `json:"currency" gorm:"not null;default:EUR;size:3"`
	Odometer    int       `json:"odometer" gorm:"default:0"`
	TripLength  float64   `json:"trip_length" gorm:"default:0;type:decimal(8,2);comment:Distance traveled since last fillup in km"`
	Notes       string    `json:"notes" gorm:"type:text"`
	CreatedAt   time.Time `json:"created_at" gorm:"autoCreateTime"`
	UpdatedAt   time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}

// FuelStopStats represents statistics for fuel consumption
type FuelStopStats struct {
	TotalStops         int       `json:"total_stops"`
	TotalLiters        float64   `json:"total_liters"`
	TotalSpent         float64   `json:"total_spent"`
	AveragePrice       float64   `json:"average_price"`
	AverageConsumption float64   `json:"average_consumption"`
	LastFillup         *FuelStop `json:"last_fillup"`
}

// FuelStopForm represents form data for creating/updating fuel stops
type FuelStopForm struct {
	Date        string  `json:"date" form:"date"`
	VehicleID   uint    `json:"vehicle_id" form:"vehicle_id"`
	StationName string  `json:"station_name" form:"station_name"`
	Location    string  `json:"location" form:"location"`
	FuelType    string  `json:"fuel_type" form:"fuel_type"`
	Liters      float64 `json:"liters" form:"liters"`
	PricePerL   float64 `json:"price_per_l" form:"price_per_l"`
	TotalPrice  float64 `json:"total_price" form:"total_price"`
	Currency    string  `json:"currency" form:"currency"`
	Odometer    int     `json:"odometer" form:"odometer"`
	TripLength  float64 `json:"trip_length" form:"trip_length"`
	Notes       string  `json:"notes" form:"notes"`
}

// UserRegistrationForm represents form data for user registration
type UserRegistrationForm struct {
	Username        string `json:"username" form:"username"`
	Email           string `json:"email" form:"email"`
	Password        string `json:"password" form:"password"`
	ConfirmPassword string `json:"confirm_password" form:"confirm_password"`
	BaseCurrency    string `json:"base_currency" form:"base_currency"`
}

// UserLoginForm represents form data for user login
type UserLoginForm struct {
	Username string `json:"username" form:"username"`
	Password string `json:"password" form:"password"`
}

// UserSettingsForm represents form data for user settings
type UserSettingsForm struct {
	Email        string `json:"email" form:"email"`
	BaseCurrency string `json:"base_currency" form:"base_currency"`
}

// MonthlyStats represents monthly statistics for fuel consumption
type MonthlyStats struct {
	Month        string  `json:"month"`
	Year         string  `json:"year"`
	TotalStops   int     `json:"total_stops"`
	TotalLiters  float64 `json:"total_liters"`
	TotalSpent   float64 `json:"total_spent"`
	AveragePrice float64 `json:"average_price"`
}

// VehicleForm represents form data for creating/updating vehicles
type VehicleForm struct {
	Name         string `json:"name" form:"name"`
	Make         string `json:"make" form:"make"`
	Model        string `json:"model" form:"model"`
	Year         int    `json:"year" form:"year"`
	LicensePlate string `json:"license_plate" form:"license_plate"`
	FuelType     string `json:"fuel_type" form:"fuel_type"`
	Notes        string `json:"notes" form:"notes"`
	IsActive     bool   `json:"is_active" form:"is_active"`
}

// ToFuelStop converts a FuelStopForm to a FuelStop
func (f *FuelStopForm) ToFuelStop(userID uint) (*FuelStop, error) {
	date, err := time.Parse("2006-01-02", f.Date)
	if err != nil {
		return nil, err
	}

	// Use EUR as default currency if not provided
	currency := f.Currency
	if currency == "" {
		currency = "EUR"
	}

	return &FuelStop{
		UserID:      userID,
		VehicleID:   f.VehicleID,
		Date:        date,
		StationName: f.StationName,
		Location:    f.Location,
		FuelType:    f.FuelType,
		Liters:      f.Liters,
		PricePerL:   f.PricePerL,
		TotalPrice:  f.TotalPrice,
		Currency:    currency,
		Odometer:    f.Odometer,
		TripLength:  f.TripLength,
		Notes:       f.Notes,
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}, nil
}

// ToVehicle converts a VehicleForm to a Vehicle
func (f *VehicleForm) ToVehicle(userID uint) *Vehicle {
	return &Vehicle{
		UserID:       userID,
		Name:         f.Name,
		Make:         f.Make,
		Model:        f.Model,
		Year:         f.Year,
		LicensePlate: f.LicensePlate,
		FuelType:     f.FuelType,
		Notes:        f.Notes,
		IsActive:     f.IsActive,
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
	}
}

// ToUser converts a UserRegistrationForm to a User
func (f *UserRegistrationForm) ToUser() (*User, error) {
	// Use EUR as default currency if not provided
	currency := f.BaseCurrency
	if currency == "" {
		currency = "EUR"
	}

	return &User{
		Username:     f.Username,
		Email:        f.Email,
		Password:     f.Password,
		BaseCurrency: currency,
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
	}, nil
}
