package com.mvrent.carrental.model;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "drivers")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Driver {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    private String name;

    private String phone;

    @Column(unique = true, nullable = false)
    @NotBlank
    private String licenceNumber;

    private LocalDate licenceExpiry;

    @Min(0)
    @ColumnDefault("0")
    @Builder.Default
    private int yearsExperience = 0;

    /** Driver category (master record of type DRIVER). */
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "category_id")
    private Category category;

    @Enumerated(EnumType.STRING)
    @ColumnDefault("'EMPLOYED'")
    @Builder.Default
    private DriverEmploymentType employmentType = DriverEmploymentType.EMPLOYED;

    /** Set when employmentType = VENDOR. */
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "vendor_id")
    private Vendor vendor;

    /* ---------- Charges ---------- */

    private BigDecimal hourlyCharge;
    private BigDecimal dailyCharge;
    private BigDecimal monthlyCharge;

    /* ---------- Availability ---------- */

    @Enumerated(EnumType.STRING)
    @ColumnDefault("'AVAILABLE'")
    @Builder.Default
    private DriverStatus status = DriverStatus.AVAILABLE;

    private String photoUrl;

    @OneToMany(mappedBy = "driver", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("expiryDate ASC")
    @Builder.Default
    private List<DriverDocument> documents = new ArrayList<>();

    @Transient
    public boolean isLicenceExpired() {
        return licenceExpiry != null && licenceExpiry.isBefore(LocalDate.now());
    }

    @Transient
    public boolean isAssignable() {
        return status == DriverStatus.AVAILABLE && !isLicenceExpired();
    }
}
