package com.cos.entity;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * JPA Entity representing a Certificate of Sponsorship (CoS)
 * Maps to the UK Visas & Immigration CoS document structure
 */
@Entity
@Table(name = "CERTIFICATE_OF_SPONSORSHIP")
@NamedQueries({
    @NamedQuery(name = "CertificateOfSponsorship.findAll",
                query = "SELECT c FROM CertificateOfSponsorship c ORDER BY c.createdAt DESC"),
    @NamedQuery(name = "CertificateOfSponsorship.findByCertNumber",
                query = "SELECT c FROM CertificateOfSponsorship c WHERE c.certificateNumber = :certNumber"),
    @NamedQuery(name = "CertificateOfSponsorship.findBySponsorLicence",
                query = "SELECT c FROM CertificateOfSponsorship c WHERE c.sponsorLicenceNumber = :licenceNumber")
})
public class CertificateOfSponsorship implements Serializable {

    private static final long serialVersionUID = 1L;

    // ─── Primary Key ────────────────────────────────────────────────────────────
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cos_seq")
    @SequenceGenerator(name = "cos_seq", sequenceName = "COS_SEQ", allocationSize = 1)
    @Column(name = "ID")
    private Long id;

    // ─── Tier and Category ───────────────────────────────────────────────────────
    @Column(name = "TIER_AND_CATEGORY", length = 200)
    private String tierAndCategory;

    // ─── Certificate of Sponsorship Status ──────────────────────────────────────
    @NotBlank(message = "Sponsor Licence Number is required")
    @Column(name = "SPONSOR_LICENCE_NUMBER", length = 50, nullable = false)
    private String sponsorLicenceNumber;

    @NotBlank(message = "Sponsor Name is required")
    @Column(name = "SPONSOR_NAME", length = 200, nullable = false)
    private String sponsorName;

    @NotBlank(message = "Certificate Number is required")
    @Column(name = "CERTIFICATE_NUMBER", length = 50, nullable = false, unique = true)
    private String certificateNumber;

    @Column(name = "CURRENT_CERT_STATUS", length = 50)
    private String currentCertStatus;

    @Column(name = "CURRENT_CERT_STATUS_DATE")
    private LocalDate currentCertStatusDate;

    @Column(name = "DATE_ASSIGNED")
    private LocalDate dateAssigned;

    @Column(name = "EXPIRY_DATE_USE_BY")
    private LocalDate expiryDateUseBy;

    @Column(name = "SPONSORSHIP_WITHDRAWN", length = 1)
    private String sponsorshipWithdrawn;

    @Column(name = "SPONSOR_NOTE", length = 1000)
    private String sponsorNote;

    @Column(name = "MIGRANT_APPLICATION_STATUS", length = 100)
    private String migrantApplicationStatus;

    // ─── Personal Information ────────────────────────────────────────────────────
    @Column(name = "FAMILY_NAME", length = 100)
    private String familyName;

    @NotBlank(message = "Given name is required")
    @Column(name = "GIVEN_NAMES", length = 200, nullable = false)
    private String givenNames;

    @Column(name = "OTHER_NAMES", length = 200)
    private String otherNames;

    @Column(name = "NATIONALITY", length = 100)
    private String nationality;

    @Column(name = "PLACE_OF_BIRTH", length = 200)
    private String placeOfBirth;

    @Column(name = "COUNTRY_OF_BIRTH", length = 100)
    private String countryOfBirth;

    @Column(name = "DATE_OF_BIRTH")
    private LocalDate dateOfBirth;

    @Column(name = "GENDER", length = 20)
    private String gender;

    @Column(name = "COUNTRY_OF_RESIDENCE", length = 100)
    private String countryOfResidence;

    // ─── Passport / Travel Document ──────────────────────────────────────────────
    @Column(name = "PASSPORT_NUMBER", length = 50)
    private String passportNumber;

    @Column(name = "PASSPORT_ISSUE_DATE")
    private LocalDate passportIssueDate;

    @Column(name = "PASSPORT_EXPIRY_DATE")
    private LocalDate passportExpiryDate;

    @Column(name = "PLACE_OF_ISSUE_PASSPORT", length = 100)
    private String placeOfIssuePassport;

    // ─── Current Home Address ────────────────────────────────────────────────────
    @Column(name = "HOME_ADDRESS", length = 300)
    private String homeAddress;

    @Column(name = "HOME_CITY_TOWN", length = 100)
    private String homeCityTown;

    @Column(name = "HOME_COUNTY_AREA", length = 100)
    private String homeCountyArea;

    @Column(name = "HOME_POSTCODE", length = 20)
    private String homePostcode;

    @Column(name = "HOME_COUNTRY", length = 100)
    private String homeCountry;

    // ─── Identification Numbers ──────────────────────────────────────────────────
    @Column(name = "UK_ID_CARD_NUMBER", length = 50)
    private String ukIdCardNumber;

    @Column(name = "UK_NATIONAL_INSURANCE_NUMBER", length = 20)
    private String ukNationalInsuranceNumber;

    @Column(name = "NATIONAL_ID_CARD_NUMBER", length = 50)
    private String nationalIdCardNumber;

    @Column(name = "EMPLOYEE_NUMBER", length = 50)
    private String employeeNumber;

    // ─── Work Dates ──────────────────────────────────────────────────────────────
    @Column(name = "WORK_START_DATE")
    private LocalDate workStartDate;

    @Column(name = "WORK_END_DATE")
    private LocalDate workEndDate;

    @Column(name = "LEAVE_REENTER_UK", length = 1)
    private String leaveReenterUk;

    @Column(name = "TOTAL_WEEKLY_HOURS")
    private Double totalWeeklyHours;

    // ─── Main Work Address ───────────────────────────────────────────────────────
    @Column(name = "WORK_ADDRESS", length = 300)
    private String workAddress;

    @Column(name = "WORK_CITY_TOWN", length = 100)
    private String workCityTown;

    @Column(name = "WORK_COUNTY_AREA", length = 100)
    private String workCountyArea;

    @Column(name = "WORK_POSTCODE", length = 20)
    private String workPostcode;

    // ─── Other Regular Work Addresses ────────────────────────────────────────────
    @Column(name = "OTHER_WORK_ADDRESSES", length = 1000)
    private String otherWorkAddresses;

    // ─── Migrant's Employment ────────────────────────────────────────────────────
    @Column(name = "JOB_TITLE", length = 200)
    private String jobTitle;

    @Column(name = "JOB_TYPE", length = 200)
    private String jobType;

    @Column(name = "JOB_DESCRIPTION", length = 2000)
    private String jobDescription;

    @Column(name = "NEW_ENTRANT", length = 1)
    private String newEntrant;

    @Column(name = "GROSS_SALARY")
    private Double grossSalary;

    @Column(name = "SALARY_PERIOD", length = 20)
    private String salaryPeriod;

    @Column(name = "APPROPRIATE_SKILL_LEVEL", length = 1)
    private String appropriateSkillLevel;

    @Column(name = "CERTIFY_MAINTENANCE", length = 1)
    private String certifyMaintenance;

    @Column(name = "ATAS_REQUIRED", length = 1)
    private String atasRequired;

    // ─── PAYE ────────────────────────────────────────────────────────────────────
    @Column(name = "PAYE_REFERENCE_SUPPLIED", length = 1)
    private String payeReferenceSupplied;

    @Column(name = "PAYE_REFERENCE_NUMBER", length = 50)
    private String payeReferenceNumber;

    // ─── PhD ─────────────────────────────────────────────────────────────────────
    @Column(name = "PHD_LEVEL_REQUIRED", length = 1)
    private String phdLevelRequired;

    // ─── Audit Fields ────────────────────────────────────────────────────────────
    @Column(name = "CREATED_AT", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @Column(name = "UPDATED_AT")
    private LocalDateTime updatedAt;

    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }

    // ─── Constructors ────────────────────────────────────────────────────────────
    public CertificateOfSponsorship() {}

    // ─── Getters and Setters ─────────────────────────────────────────────────────
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getTierAndCategory() { return tierAndCategory; }
    public void setTierAndCategory(String tierAndCategory) { this.tierAndCategory = tierAndCategory; }

    public String getSponsorLicenceNumber() { return sponsorLicenceNumber; }
    public void setSponsorLicenceNumber(String sponsorLicenceNumber) { this.sponsorLicenceNumber = sponsorLicenceNumber; }

    public String getSponsorName() { return sponsorName; }
    public void setSponsorName(String sponsorName) { this.sponsorName = sponsorName; }

    public String getCertificateNumber() { return certificateNumber; }
    public void setCertificateNumber(String certificateNumber) { this.certificateNumber = certificateNumber; }

    public String getCurrentCertStatus() { return currentCertStatus; }
    public void setCurrentCertStatus(String currentCertStatus) { this.currentCertStatus = currentCertStatus; }

    public LocalDate getCurrentCertStatusDate() { return currentCertStatusDate; }
    public void setCurrentCertStatusDate(LocalDate currentCertStatusDate) { this.currentCertStatusDate = currentCertStatusDate; }

    public LocalDate getDateAssigned() { return dateAssigned; }
    public void setDateAssigned(LocalDate dateAssigned) { this.dateAssigned = dateAssigned; }

    public LocalDate getExpiryDateUseBy() { return expiryDateUseBy; }
    public void setExpiryDateUseBy(LocalDate expiryDateUseBy) { this.expiryDateUseBy = expiryDateUseBy; }

    public String getSponsorshipWithdrawn() { return sponsorshipWithdrawn; }
    public void setSponsorshipWithdrawn(String sponsorshipWithdrawn) { this.sponsorshipWithdrawn = sponsorshipWithdrawn; }

    public String getSponsorNote() { return sponsorNote; }
    public void setSponsorNote(String sponsorNote) { this.sponsorNote = sponsorNote; }

    public String getMigrantApplicationStatus() { return migrantApplicationStatus; }
    public void setMigrantApplicationStatus(String migrantApplicationStatus) { this.migrantApplicationStatus = migrantApplicationStatus; }

    public String getFamilyName() { return familyName; }
    public void setFamilyName(String familyName) { this.familyName = familyName; }

    public String getGivenNames() { return givenNames; }
    public void setGivenNames(String givenNames) { this.givenNames = givenNames; }

    public String getOtherNames() { return otherNames; }
    public void setOtherNames(String otherNames) { this.otherNames = otherNames; }

    public String getNationality() { return nationality; }
    public void setNationality(String nationality) { this.nationality = nationality; }

    public String getPlaceOfBirth() { return placeOfBirth; }
    public void setPlaceOfBirth(String placeOfBirth) { this.placeOfBirth = placeOfBirth; }

    public String getCountryOfBirth() { return countryOfBirth; }
    public void setCountryOfBirth(String countryOfBirth) { this.countryOfBirth = countryOfBirth; }

    public LocalDate getDateOfBirth() { return dateOfBirth; }
    public void setDateOfBirth(LocalDate dateOfBirth) { this.dateOfBirth = dateOfBirth; }

    public String getGender() { return gender; }
    public void setGender(String gender) { this.gender = gender; }

    public String getCountryOfResidence() { return countryOfResidence; }
    public void setCountryOfResidence(String countryOfResidence) { this.countryOfResidence = countryOfResidence; }

    public String getPassportNumber() { return passportNumber; }
    public void setPassportNumber(String passportNumber) { this.passportNumber = passportNumber; }

    public LocalDate getPassportIssueDate() { return passportIssueDate; }
    public void setPassportIssueDate(LocalDate passportIssueDate) { this.passportIssueDate = passportIssueDate; }

    public LocalDate getPassportExpiryDate() { return passportExpiryDate; }
    public void setPassportExpiryDate(LocalDate passportExpiryDate) { this.passportExpiryDate = passportExpiryDate; }

    public String getPlaceOfIssuePassport() { return placeOfIssuePassport; }
    public void setPlaceOfIssuePassport(String placeOfIssuePassport) { this.placeOfIssuePassport = placeOfIssuePassport; }

    public String getHomeAddress() { return homeAddress; }
    public void setHomeAddress(String homeAddress) { this.homeAddress = homeAddress; }

    public String getHomeCityTown() { return homeCityTown; }
    public void setHomeCityTown(String homeCityTown) { this.homeCityTown = homeCityTown; }

    public String getHomeCountyArea() { return homeCountyArea; }
    public void setHomeCountyArea(String homeCountyArea) { this.homeCountyArea = homeCountyArea; }

    public String getHomePostcode() { return homePostcode; }
    public void setHomePostcode(String homePostcode) { this.homePostcode = homePostcode; }

    public String getHomeCountry() { return homeCountry; }
    public void setHomeCountry(String homeCountry) { this.homeCountry = homeCountry; }

    public String getUkIdCardNumber() { return ukIdCardNumber; }
    public void setUkIdCardNumber(String ukIdCardNumber) { this.ukIdCardNumber = ukIdCardNumber; }

    public String getUkNationalInsuranceNumber() { return ukNationalInsuranceNumber; }
    public void setUkNationalInsuranceNumber(String ukNationalInsuranceNumber) { this.ukNationalInsuranceNumber = ukNationalInsuranceNumber; }

    public String getNationalIdCardNumber() { return nationalIdCardNumber; }
    public void setNationalIdCardNumber(String nationalIdCardNumber) { this.nationalIdCardNumber = nationalIdCardNumber; }

    public String getEmployeeNumber() { return employeeNumber; }
    public void setEmployeeNumber(String employeeNumber) { this.employeeNumber = employeeNumber; }

    public LocalDate getWorkStartDate() { return workStartDate; }
    public void setWorkStartDate(LocalDate workStartDate) { this.workStartDate = workStartDate; }

    public LocalDate getWorkEndDate() { return workEndDate; }
    public void setWorkEndDate(LocalDate workEndDate) { this.workEndDate = workEndDate; }

    public String getLeaveReenterUk() { return leaveReenterUk; }
    public void setLeaveReenterUk(String leaveReenterUk) { this.leaveReenterUk = leaveReenterUk; }

    public Double getTotalWeeklyHours() { return totalWeeklyHours; }
    public void setTotalWeeklyHours(Double totalWeeklyHours) { this.totalWeeklyHours = totalWeeklyHours; }

    public String getWorkAddress() { return workAddress; }
    public void setWorkAddress(String workAddress) { this.workAddress = workAddress; }

    public String getWorkCityTown() { return workCityTown; }
    public void setWorkCityTown(String workCityTown) { this.workCityTown = workCityTown; }

    public String getWorkCountyArea() { return workCountyArea; }
    public void setWorkCountyArea(String workCountyArea) { this.workCountyArea = workCountyArea; }

    public String getWorkPostcode() { return workPostcode; }
    public void setWorkPostcode(String workPostcode) { this.workPostcode = workPostcode; }

    public String getOtherWorkAddresses() { return otherWorkAddresses; }
    public void setOtherWorkAddresses(String otherWorkAddresses) { this.otherWorkAddresses = otherWorkAddresses; }

    public String getJobTitle() { return jobTitle; }
    public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; }

    public String getJobType() { return jobType; }
    public void setJobType(String jobType) { this.jobType = jobType; }

    public String getJobDescription() { return jobDescription; }
    public void setJobDescription(String jobDescription) { this.jobDescription = jobDescription; }

    public String getNewEntrant() { return newEntrant; }
    public void setNewEntrant(String newEntrant) { this.newEntrant = newEntrant; }

    public Double getGrossSalary() { return grossSalary; }
    public void setGrossSalary(Double grossSalary) { this.grossSalary = grossSalary; }

    public String getSalaryPeriod() { return salaryPeriod; }
    public void setSalaryPeriod(String salaryPeriod) { this.salaryPeriod = salaryPeriod; }

    public String getAppropriateSkillLevel() { return appropriateSkillLevel; }
    public void setAppropriateSkillLevel(String appropriateSkillLevel) { this.appropriateSkillLevel = appropriateSkillLevel; }

    public String getCertifyMaintenance() { return certifyMaintenance; }
    public void setCertifyMaintenance(String certifyMaintenance) { this.certifyMaintenance = certifyMaintenance; }

    public String getAtasRequired() { return atasRequired; }
    public void setAtasRequired(String atasRequired) { this.atasRequired = atasRequired; }

    public String getPayeReferenceSupplied() { return payeReferenceSupplied; }
    public void setPayeReferenceSupplied(String payeReferenceSupplied) { this.payeReferenceSupplied = payeReferenceSupplied; }

    public String getPayeReferenceNumber() { return payeReferenceNumber; }
    public void setPayeReferenceNumber(String payeReferenceNumber) { this.payeReferenceNumber = payeReferenceNumber; }

    public String getPhdLevelRequired() { return phdLevelRequired; }
    public void setPhdLevelRequired(String phdLevelRequired) { this.phdLevelRequired = phdLevelRequired; }

    public LocalDateTime getCreatedAt() { return createdAt; }
    public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }

    public LocalDateTime getUpdatedAt() { return updatedAt; }
    public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }

    @Override
    public String toString() {
        return "CertificateOfSponsorship{id=" + id + ", certNumber=" + certificateNumber + ", givenNames=" + givenNames + "}";
    }
}