<?php

namespace App\Services;

use App\Enums\UserType;
use App\Models\User;
use App\Traits\UploadsMedia;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class EmployeeService
{
    use UploadsMedia;

    public function getAllEmployees(array $filters = [], int $perPage = 10)
    {
        return User::query()
            ->where('type', UserType::EMPLOYEE)
            ->with(['employeeProfile.manager', 'employeeProfile.departmentRel'])
            ->when(filled($filters['search'] ?? null), function ($query) use ($filters) {
                $query->where(function ($q) use ($filters) {
                    $q->where('name', 'like', '%'.$filters['search'].'%')
                        ->orWhere('email', 'like', '%'.$filters['search'].'%')
                        ->orWhereHas('employeeProfile', function ($q2) use ($filters) {
                            $q2->where('phone', 'like', '%'.$filters['search'].'%')
                                ->orWhere('job_title', 'like', '%'.$filters['search'].'%');
                        });
                });
            })
            ->when(filled($filters['department'] ?? null), function ($query) use ($filters) {
                $query->whereHas('employeeProfile', function ($q) use ($filters) {
                    $q->where('department_id', $filters['department']);
                });
            })
            ->when(filled($filters['status'] ?? null), function ($query) use ($filters) {
                $query->where('status', $filters['status']);
            })
            ->latest()
            ->paginate($perPage);
    }

    public function createEmployee(array $data)
    {
        return DB::transaction(function () use ($data) {
            $user = User::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'password' => Hash::make($data['password']),
                'type' => UserType::EMPLOYEE,
                'status' => $data['status'] ?? 'active',
                'profile_image' => $this->handleUpload($data, 'profile_image', 'employees/profiles'),
            ]);

            // Handle Documents
            $idCardPath = $this->handleUpload($data, 'id_card');
            $contractPath = $this->handleUpload($data, 'contract');
            $taxFormPath = $this->handleUpload($data, 'tax_form');

            // Get department name if ID is provided, for backward compatibility
            $departmentName = $data['department'] ?? null;
            if (isset($data['department_id'])) {
                $dept = \App\Models\Department::find($data['department_id']);
                if ($dept) {
                    $departmentName = $dept->name;
                }
            }

            $user->employeeProfile()->create([
                'phone' => $data['phone'] ?? null,
                'personal_email' => $data['personal_email'] ?? null,
                'personal_phone' => $data['personal_phone'] ?? null,
                'date_of_birth' => $data['date_of_birth'] ?? null,
                'address' => $data['address'] ?? null,
                'city' => $data['city'] ?? null,
                'job_title' => $data['job_title'] ?? null,
                'department' => $departmentName,
                'department_id' => $data['department_id'] ?? null,
                'manager_id' => filled($data['manager_id'] ?? null) ? (int) $data['manager_id'] : null,
                'joining_date' => $data['joining_date'] ?? null,
                'emergency_contact_name' => $data['emergency_contact_name'] ?? null,
                'emergency_contact_phone' => $data['emergency_contact_phone'] ?? null,
                'id_card_path' => $idCardPath,
                'contract_path' => $contractPath,
                'tax_form_path' => $taxFormPath,
            ]);

            return $user;
        });
    }

    public function updateEmployee(User $user, array $data)
    {
        return DB::transaction(function () use ($user, $data) {
            $userUpdateData = [
                'name' => $data['name'],
                'email' => $data['email'],
                'status' => $data['status'] ?? $user->status,
            ];

            if ($profileImagePath = $this->handleUpload($data, 'profile_image', 'employees/profiles')) {
                $userUpdateData['profile_image'] = $profileImagePath;
            }

            $user->update($userUpdateData);

            if (isset($data['password']) && filled($data['password'])) {
                $user->update(['password' => Hash::make($data['password'])]);
            }

            // Get department name if ID is provided, for backward compatibility
            $departmentName = $data['department'] ?? null;
            if (isset($data['department_id'])) {
                $dept = \App\Models\Department::find($data['department_id']);
                if ($dept) {
                    $departmentName = $dept->name;
                }
            }

            // Handle Documents with replacement logic
            $profileData = [
                'phone' => $data['phone'] ?? null,
                'personal_email' => $data['personal_email'] ?? null,
                'personal_phone' => $data['personal_phone'] ?? null,
                'date_of_birth' => $data['date_of_birth'] ?? null,
                'address' => $data['address'] ?? null,
                'city' => $data['city'] ?? null,
                'job_title' => $data['job_title'] ?? null,
                'department' => $departmentName,
                'department_id' => $data['department_id'] ?? null,
                'manager_id' => filled($data['manager_id'] ?? null) ? (int) $data['manager_id'] : null,
                'joining_date' => $data['joining_date'] ?? null,
                'emergency_contact_name' => $data['emergency_contact_name'] ?? null,
                'emergency_contact_phone' => $data['emergency_contact_phone'] ?? null,
            ];

            // Append new files if uploaded
            if ($path = $this->handleUpload($data, 'id_card')) {
                // Delete old? optional
                $profileData['id_card_path'] = $path;
            }
            if ($path = $this->handleUpload($data, 'contract')) {
                $profileData['contract_path'] = $path;
            }
            if ($path = $this->handleUpload($data, 'tax_form')) {
                $profileData['tax_form_path'] = $path;
            }

            $user->employeeProfile()->updateOrCreate(
                ['user_id' => $user->id],
                $profileData
            );

            return $user;
        });
    }

    private function handleUpload(array $data, string $key, string $folder = 'employees/documents'): ?string
    {
        if (isset($data[$key]) && $data[$key] instanceof \Illuminate\Http\UploadedFile) {
            return $this->uploadOne($data[$key], $folder, 'public');
        }

        return null;
    }

    public function getDepartments()
    {
        return \App\Models\Department::where('status', true)->select('id', 'name')->get();
    }
}
