import { ApiProperty } from "@nestjs/swagger"
import {
  IsNotEmpty,
  IsOptional,
  IsInt,
  IsString,
  IsEmail,
  IsDateString,
  IsNumber,
  IsArray,
  ValidateNested,
  IsIn,
  MaxLength,
} from "class-validator"
import { Type, Transform } from "class-transformer"
import { validationMessage } from "../../../utils/helpers"
import { messageKey } from "../../../constants/message-keys"

export class EmployeeSalarySettingDto {
  @ApiProperty({
    description: "Salary Setting ID",
    example: 1,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "salary_setting_id",
    }),
  })
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "salary_setting_id",
      ":type": "integer",
    }),
  })
  salary_setting_id: number

  @ApiProperty({
    description:
      "Individual value for this salary setting (percentage or fixed amount)",
    example: "15.5",
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "individual_value",
    }),
  })
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "individual_value",
      ":type": "string",
    }),
  })
  individual_value: string
}

export class CreateEmployeeDto {
  @ApiProperty({
    description: "Department ID",
    example: 1,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "department_id",
      ":type": "integer",
    }),
  })
  department_id?: number

  @ApiProperty({
    description: "Sub Department ID",
    example: 1,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "sub_department_id",
      ":type": "integer",
    }),
  })
  sub_department_id?: number

  @ApiProperty({
    description: "Role ID",
    example: 1,
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "role_id",
    }),
  })
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "role_id",
      ":type": "integer",
    }),
  })
  role_id: number

  @ApiProperty({
    description: "Team Lead ID (Employee ID who is the team lead)",
    example: 1,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "team_lead_id",
      ":type": "integer",
    }),
  })
  team_lead_id?: number

  @ApiProperty({
    description: "Employee First Name",
    example: "John",
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "first_name",
    }),
  })
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "first_name",
      ":type": "string",
    }),
  })
  first_name: string

  @ApiProperty({
    description: "Employee Last Name",
    example: "Doe",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "last_name",
      ":type": "string",
    }),
  })
  last_name?: string

  @ApiProperty({
    description: "Employee Email",
    example: "john.doe@company.com",
    required: false,
  })
  @IsOptional()
  @IsEmail(
    {},
    {
      message: validationMessage(messageKey.email_invalid),
    },
  )
  email?: string

  @ApiProperty({
    description: "Employee Contact Number",
    example: "+1234567890",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "contact_no",
      ":type": "string",
    }),
  })
  contact_no?: string

  @ApiProperty({
    description: "Employee Joining Date",
    example: "2024-01-15",
    required: false,
  })
  @IsOptional()
  @IsDateString(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "joining_date",
        ":type": "date (YYYY-MM-DD)",
      }),
    },
  )
  joining_date?: string

  @ApiProperty({
    description: "Employee Status",
    example: 1,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "status",
      ":type": "integer",
    }),
  })
  status?: number

  @ApiProperty({
    description: "Employee Type",
    example: "employee",
    enum: ["employee", "trainee", "contract"],
  })
  @IsNotEmpty({
    message: validationMessage(messageKey.field_required, {
      ":field": "employee_type",
    }),
  })
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "employee_type",
      ":type": "string",
    }),
  })
  @IsIn(["employee", "trainee", "contract"], {
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "employee_type",
      ":type": "employee, trainee or contract",
    }),
  })
  employee_type: string

  @ApiProperty({
    description: "Gross Salary (Base salary for calculations, can be 0)",
    example: 50000.0,
    required: false,
  })
  @IsOptional()
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "gross_salary",
        ":type": "number",
      }),
    },
  )
  gross_salary?: number

  @ApiProperty({
    description: "Stipend amount for trainees",
    example: 5000.0,
    required: false,
  })
  @IsOptional()
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "stipend",
        ":type": "number",
      }),
    },
  )
  stipend?: number

  @ApiProperty({
    description: "Tax regime type",
    example: "new",
    enum: ["old", "new"],
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "regime_type",
      ":type": "string",
    }),
  })
  @IsIn(["old", "new"], {
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "regime_type",
      ":type": "old or new",
    }),
  })
  regime_type?: string

  @ApiProperty({
    description: "Array of salary settings with individual values",
    example: [
      {
        salary_setting_id: 1,
        individual_value: "15.5",
      },
      {
        salary_setting_id: 2,
        individual_value: "2000",
      },
    ],
    required: false,
  })
  @IsOptional()
  @Transform(({ value }) => {
    // Handle FormData case where value comes as JSON string
    if (typeof value === "string") {
      try {
        const parsed = JSON.parse(value)
        return Array.isArray(parsed) ? parsed : []
      } catch (error) {
        // If parsing fails, return empty array to trigger validation error
        return []
      }
    }
    // Handle application/json case where value is already an array
    if (Array.isArray(value)) {
      return value
    }
    // Handle null/undefined cases
    if (value === null || value === undefined) {
      return undefined
    }
    // For any other type, return empty array to trigger validation error
    return []
  })
  @IsArray({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "salary_settings",
      ":type": "array",
    }),
  })
  @ValidateNested({ each: true })
  @Type(() => EmployeeSalarySettingDto)
  salary_settings?: EmployeeSalarySettingDto[]

  // Employee Information Fields
  @ApiProperty({
    description: "Employee Address",
    example: "123 Main Street, City, State, Country",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "address",
      ":type": "string",
    }),
  })
  address?: string

  @ApiProperty({
    description: "Gender",
    example: "Male",
    enum: ["Male", "Female", "Other"],
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "gender",
      ":type": "string",
    }),
  })
  @MaxLength(10, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "gender",
      ":length": "10",
    }),
  })
  gender?: string

  @ApiProperty({
    description: "Alternate Mobile Number",
    example: "+1234567890",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "alternate_mobile_number",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "alternate_mobile_number",
      ":length": "20",
    }),
  })
  alternate_mobile_number?: string

  @ApiProperty({
    description: "Date of Birth",
    example: "1990-01-15",
    required: false,
  })
  @IsOptional()
  @IsDateString(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "date_of_birth",
        ":type": "valid date (YYYY-MM-DD)",
      }),
    },
  )
  date_of_birth?: string

  @ApiProperty({
    description: "Marital Status",
    example: "Single",
    enum: ["Single", "Married", "Divorced", "Widowed"],
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "marital_status",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "marital_status",
      ":length": "20",
    }),
  })
  marital_status?: string

  @ApiProperty({
    description: "Parents Name",
    example: "John Doe Sr.",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "parents_name",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "parents_name",
      ":length": "255",
    }),
  })
  parents_name?: string

  @ApiProperty({
    description: "Parents Contact Number",
    example: "+0987654321",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "parents_contact_number",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "parents_contact_number",
      ":length": "20",
    }),
  })
  parents_contact_number?: string

  @ApiProperty({
    description: "Blood Group",
    example: "O+",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "blood_group",
      ":type": "string",
    }),
  })
  @MaxLength(10, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "blood_group",
      ":length": "10",
    }),
  })
  blood_group?: string

  @ApiProperty({
    description: "Native Place",
    example: "Mumbai, Maharashtra",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "native_place",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "native_place",
      ":length": "255",
    }),
  })
  native_place?: string

  @ApiProperty({
    description: "Aadhar Card Number",
    example: "1234-5678-9012",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "aadhar_card",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "aadhar_card",
      ":length": "20",
    }),
  })
  aadhar_card?: string

  @ApiProperty({
    description: "PAN Card Number",
    example: "ABCDE1234F",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "pan_card_number",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "pan_card_number",
      ":length": "20",
    }),
  })
  pan_card_number?: string

  @ApiProperty({
    description: "Education Qualification",
    example: "Bachelor of Engineering",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "education_qualification",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "education_qualification",
      ":length": "255",
    }),
  })
  education_qualification?: string

  @ApiProperty({
    description: "Total Work Experience in Years",
    example: 5.5,
    required: false,
  })
  @IsOptional()
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "total_work_experience_years",
        ":type": "number",
      }),
    },
  )
  total_work_experience_years?: number

  // ── Employment Details (employees table) ────────────────────────────────────

  @ApiProperty({
    description: "Employee Number (assigned by HR)",
    example: "EMP-001",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "employee_number",
      ":type": "string",
    }),
  })
  @MaxLength(50, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "employee_number",
      ":length": "50",
    }),
  })
  employee_number?: string

  @ApiProperty({
    description: "Work Location",
    example: "WFO",
    enum: ["WFO", "WFH", "Hybrid"],
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "work_location",
      ":type": "string",
    }),
  })
  @IsIn(["WFO", "WFH", "Hybrid"], {
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "work_location",
      ":type": "WFO, WFH or Hybrid",
    }),
  })
  work_location?: string

  @ApiProperty({
    description: "Probation Period in days",
    example: 90,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "probation_period",
      ":type": "integer",
    }),
  })
  probation_period?: number

  @ApiProperty({
    description: "Notice Period in days",
    example: 60,
    required: false,
  })
  @IsOptional()
  @IsInt({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "notice_period",
      ":type": "integer",
    }),
  })
  notice_period?: number

  // ── Personal Details (employee_information table) ───────────────────────────

  @ApiProperty({
    description: "Personal Email ID",
    example: "john.personal@gmail.com",
    required: false,
  })
  @IsOptional()
  @IsEmail(
    {},
    {
      message: validationMessage(messageKey.email_invalid),
    },
  )
  personal_email?: string

  @ApiProperty({
    description: "Emergency Contact Name",
    example: "Jane Doe",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "emergency_contact_name",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "emergency_contact_name",
      ":length": "255",
    }),
  })
  emergency_contact_name?: string

  @ApiProperty({
    description: "Relationship with Emergency Contact",
    example: "Spouse",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "emergency_contact_relationship",
      ":type": "string",
    }),
  })
  @MaxLength(100, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "emergency_contact_relationship",
      ":length": "100",
    }),
  })
  emergency_contact_relationship?: string

  @ApiProperty({
    description: "Emergency Contact Number",
    example: "+9876543210",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "emergency_contact_number",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "emergency_contact_number",
      ":length": "20",
    }),
  })
  emergency_contact_number?: string

  // ── Address Details (employee_information table) ────────────────────────────

  @ApiProperty({
    description: "Permanent Address",
    example: "456 Home Town, Village, District",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "permanent_address",
      ":type": "string",
    }),
  })
  permanent_address?: string

  @ApiProperty({
    description: "Pincode",
    example: "400001",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "pincode",
      ":type": "string",
    }),
  })
  @MaxLength(10, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "pincode",
      ":length": "10",
    }),
  })
  pincode?: string

  @ApiProperty({
    description: "City name",
    example: "Mumbai",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "city",
      ":type": "string",
    }),
  })
  city?: string

  @ApiProperty({
    description: "State name",
    example: "Maharashtra",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "state",
      ":type": "string",
    }),
  })
  state?: string

  // ── Experience Details (employee_information table) ─────────────────────────

  @ApiProperty({
    description: "Previous Company Name",
    example: "Acme Corp",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "previous_company_name",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "previous_company_name",
      ":length": "255",
    }),
  })
  previous_company_name?: string

  @ApiProperty({
    description: "Previous Designation",
    example: "Senior Developer",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "previous_designation",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "previous_designation",
      ":length": "255",
    }),
  })
  previous_designation?: string

  @ApiProperty({
    description: "Last Drawn Salary",
    example: 45000.0,
    required: false,
  })
  @IsOptional()
  @IsNumber(
    {},
    {
      message: validationMessage(messageKey.field_type_validation_error, {
        ":field": "last_salary",
        ":type": "number",
      }),
    },
  )
  last_salary?: number

  // ── Bank Details (employee_information table) ───────────────────────────────

  @ApiProperty({
    description: "Bank Name",
    example: "State Bank of India",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "bank_name",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "bank_name",
      ":length": "255",
    }),
  })
  bank_name?: string

  @ApiProperty({
    description: "Bank Account Number",
    example: "1234567890123456",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "account_number",
      ":type": "string",
    }),
  })
  @MaxLength(50, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "account_number",
      ":length": "50",
    }),
  })
  account_number?: string

  @ApiProperty({
    description: "IFSC Code",
    example: "SBIN0001234",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "ifsc_code",
      ":type": "string",
    }),
  })
  @MaxLength(20, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "ifsc_code",
      ":length": "20",
    }),
  })
  ifsc_code?: string

  @ApiProperty({
    description: "Account Holder Name",
    example: "John Doe",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "account_holder_name",
      ":type": "string",
    }),
  })
  @MaxLength(255, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "account_holder_name",
      ":length": "255",
    }),
  })
  account_holder_name?: string

  // ── Identity Details (employee_information table) ───────────────────────────

  @ApiProperty({
    description: "UAN (Universal Account Number for PF)",
    example: "100123456789",
    required: false,
  })
  @IsOptional()
  @IsString({
    message: validationMessage(messageKey.field_type_validation_error, {
      ":field": "uan",
      ":type": "string",
    }),
  })
  @MaxLength(30, {
    message: validationMessage(messageKey.field_max_validation_error, {
      ":field": "uan",
      ":length": "30",
    }),
  })
  uan?: string
}
