<?php

namespace Tests\Unit;

use App\Support\EmployeeValidation;
use Illuminate\Support\Facades\Validator;
use Tests\TestCase;

class EmployeeValidationRulesTest extends TestCase
{
    public function test_normalize_lowercases_email_and_uppercases_pan(): void
    {
        $normalized = EmployeeValidation::normalize([
            'email' => '  Mixed.Case@Example.COM ',
            'pan_number' => 'abcde1234f',
            'phone' => '  ',
            'gender' => ' Male ',
        ]);

        $this->assertSame('mixed.case@example.com', $normalized['email']);
        $this->assertSame('ABCDE1234F', $normalized['pan_number']);
        $this->assertNull($normalized['phone']);
        $this->assertSame('male', $normalized['gender']);
    }

    public function test_format_rules_reject_reported_invalid_values(): void
    {
        $data = EmployeeValidation::normalize([
            'name' => 'John123',
            'email' => 'user@example.com',
            'password' => 'password123',
            'phone' => '987654321',
            'father_name' => 'Dad9',
            'joining_date' => '2024-06-01',
            'probation_end_date' => '2024-12-01',
            'confirmation_date' => '2024-11-01',
            'pf_join_date' => '2024-05-01',
            'pan_number' => '1234567890',
            'work_state' => 'State99',
            'pt_location' => 'Hyd@bad',
            'account_holder_name' => 'John@Doe',
            'city' => 'Hyd!',
            'designation_id' => null,
            'location_id' => null,
            'shift_id' => null,
            'report_to' => null,
        ]);

        $rules = EmployeeValidation::formRules(null, null, true);
        // Avoid DB-backed rules in this environment.
        unset($rules['email'], $rules['employee_number'], $rules['designation_id'], $rules['location_id'], $rules['shift_id'], $rules['report_to'], $rules['department_id'], $rules['salary_group_id'], $rules['role_id']);

        $validator = Validator::make($data, $rules, EmployeeValidation::messages());

        $this->assertTrue($validator->fails());
        $this->assertTrue($validator->errors()->has('name'));
        $this->assertTrue($validator->errors()->has('phone'));
        $this->assertTrue($validator->errors()->has('father_name'));
        $this->assertTrue($validator->errors()->has('confirmation_date'));
        $this->assertTrue($validator->errors()->has('pf_join_date'));
        $this->assertTrue($validator->errors()->has('pan_number'));
        $this->assertTrue($validator->errors()->has('work_state'));
        $this->assertTrue($validator->errors()->has('pt_location'));
        $this->assertTrue($validator->errors()->has('account_holder_name'));
        $this->assertTrue($validator->errors()->has('city'));
    }

    public function test_format_rules_accept_valid_values(): void
    {
        $data = EmployeeValidation::normalize([
            'name' => 'Valid User',
            'password' => 'password123',
            'phone' => '9876543210',
            'gender' => 'Female',
            'father_name' => 'Valid Father',
            'joining_date' => '2024-06-01',
            'probation_end_date' => '2024-12-01',
            'confirmation_date' => '2024-12-15',
            'pf_join_date' => '2024-06-01',
            'pan_number' => 'abcde1234f',
            'work_state' => 'Telangana',
            'pt_location' => 'Hyderabad 1',
            'account_holder_name' => 'Valid User',
            'city' => 'Hyderabad',
        ]);

        $rules = EmployeeValidation::formRules(null, null, true);
        unset($rules['email'], $rules['employee_number'], $rules['designation_id'], $rules['location_id'], $rules['shift_id'], $rules['report_to'], $rules['department_id'], $rules['salary_group_id'], $rules['role_id']);

        $validator = Validator::make($data, $rules, EmployeeValidation::messages());

        $this->assertFalse($validator->fails(), $validator->errors()->toJson());
        $this->assertSame('ABCDE1234F', $data['pan_number']);
        $this->assertSame('female', $data['gender']);
    }

    public function test_required_work_fields_are_present_on_form_rules(): void
    {
        $rules = EmployeeValidation::formRules(null, 1, true);

        $this->assertContains('required', $rules['designation_id']);
        $this->assertContains('required', $rules['location_id']);
        $this->assertContains('required', $rules['shift_id']);
        $this->assertContains('required', $rules['report_to']);
    }
}
