<?php

namespace App\Http\Controllers\Admin;

use App\Department;
use App\Employee;
use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\EmployeeDetailResource;
use App\Http\Resources\Admin\EmployeeResource;
use App\Http\Resources\Admin\EmployeeShortResource;
use App\LeaveHistory;
use App\Level;
use App\LevelHistory;
use App\Position;
use App\PositionHistory;
use App\SeverancePayment;
use App\TransitionPoint;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Validator;
use DB;

class EmployeeController extends Controller
{
	const ITEM_PER_PAGE = 100;
	
	private $levelTypes = [
		'L0' => 0,
		'L1' => 1,
		'L2' => 2,
	];
	
	private $courses = [
		'グローバル' => 1, // Global
		'ローカル'   => 2,   // Local
	];
	
	private $recruitmentMethods = [
		'キャリア' => 1,    // Tuyển dụng có kinh nghiệm
		'新卒'     => 2,        // Tuyển dụng mới tốt nghiệp
		'中途'     => 3         // Tuyển dụng giữa kỳ
	];
	
	private $genders = [
		'男性'   => 1,  // Nam
		'女性'   => 2,  // Nữ
		'その他' => 3 // Khác
	];
	
	public function index(Request $request)
	{
		$searchParams = $request->all();
		$list = Employee::query();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$keyword = Arr::get($searchParams, 'keyword', '');
		$status = Arr::get($searchParams, 'status', '');
		$departmentId = Arr::get($searchParams, 'department_id', null);
		$positionId = Arr::get($searchParams, 'position_id', '');
		$employmentStatus = Arr::get($searchParams, 'employment_status', '');
		$employeeType = Arr::get($searchParams, 'employee_type', '');
		
		if (!empty($keyword)) {
			$list->where(function ($query) use ($keyword) {
				$query->where('full_name', 'LIKE', '%' . $keyword . '%')
					->orWhere('full_name_kana', 'LIKE', '%' . $keyword . '%')
					->orWhere('employee_code', 'LIKE', '%' . $keyword . '%')
					->orWhere('work_email', 'LIKE', '%' . $keyword . '%')
					->orWhere('personal_email', 'LIKE', '%' . $keyword . '%')
					->orWhere('phone', 'LIKE', '%' . $keyword . '%')
					->orWhere('mobile_phone', 'LIKE', '%' . $keyword . '%');
			});
		}
		
		if ($status !== null && $status !== '' && in_array($status, [0, 1])) {
			$list->where('is_activated', $status);
		}
		
		if (is_array($departmentId) && count($departmentId) > 0) {
			$lastDepartmentId = $departmentId[count($departmentId) - 1];
			$allChildrenIds = Department::getAllChildrenIds($lastDepartmentId);
			
			//$listIds = Department::where('parent_id', $lastDepartmentId)->pluck('id')->toArray();
			$list->whereIn('department_id', $allChildrenIds);
		}
		
		if (!empty($positionId)) {
			$list->where('position_id', $positionId);
		}
		
		if ($employmentStatus != null && $employmentStatus != '' && $employmentStatus != 0) {
			if ($employmentStatus == 4) {
				$currentYear = Carbon::now()->year;
				$retirementAge = (integer)config('settings.retirement_age');
				$retirementAge = (!$retirementAge || $retirementAge < 10 || $retirementAge > 100) ? 60 : $retirementAge;
				$retirementBirthYear = $currentYear - ($retirementAge - 1);
				$startDate = Carbon::createFromDate($retirementBirthYear, 1, 1)->startOfDay();
				$endDate = Carbon::createFromDate($retirementBirthYear, 12, 31)->endOfDay();
				$list->working()
					->whereNotNull('date_of_birth')
					->whereBetween('date_of_birth', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')]);
			} else {
				$list->where('employment_status', $employmentStatus);
			}
		}
		
		if (!empty($employeeType)) {
			$list->where('employee_type', $employeeType);
		}
		
		$list->with(['department', 'position', 'level'])->orderBy('id');
		
		return EmployeeResource::collection($list->paginate($limit));
	}
	
	public function all(Request $request)
	{
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$list = Employee::select('id', 'employee_code', 'full_name', 'full_name_kana', 'department_id', 'position_id')
			->with(['department:id,name', 'position:id,name'])
			->orderBy('employee_code')
			->orderBy('id');
		
		return EmployeeResource::collection($list->paginate($limit));
	}
	
	public function available(Request $request)
	{
		$searchParams = $request->all();
		$ignoreId = Arr::get($searchParams, 'ignoreId', '');
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		
		$list = Employee::select('id', 'employee_code', 'full_name', 'full_name_kana', 'department_id', 'position_id')
			->with(['department:id,name', 'position:id,name'])
			->where('employment_status', 1); // Chỉ lấy nhân viên đang làm việc
		
		if ($ignoreId) {
			$list->where('id', '!=', $ignoreId);
		}
		
		$list->orderBy('employee_code')->orderBy('id');
		
		return EmployeeResource::collection($list->paginate($limit));
	}
	
	public function availableSeverance(Request $request)
	{
		$searchParams = $request->all();
		$limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
		$keyword = Arr::get($searchParams, 'keyword', '');
		$status = Arr::get($searchParams, 'status', '');
		$departmentId = Arr::get($searchParams, 'department_id', null);
		$positionId = Arr::get($searchParams, 'position_id', '');
		$employmentStatus = Arr::get($searchParams, 'employment_status', '');
		$employeeType = Arr::get($searchParams, 'employee_type', '');
		
		$list = Employee::select(
			'id', 'employee_code', 'first_name', 'last_name', 'first_name_kana', 'last_name_kana',
			'full_name', 'full_name_kana', 'date_of_birth', 'join_date',
			'department_id', 'employment_status', 'resigned_date', 'resigned_reason'
		)->with(['department'])->whereNotNull('join_date');
		
		$onlyViewIds = SeverancePayment::where('status', 1)->pluck('employee_id')->toArray();
		if (count($onlyViewIds) > 0) {
			$list->whereNotIn('id', $onlyViewIds);
		}
		
		if (!empty($keyword)) {
			$list->where(function ($query) use ($keyword) {
				$query->where('full_name', 'LIKE', '%' . $keyword . '%')
					->orWhere('full_name_kana', 'LIKE', '%' . $keyword . '%')
					->orWhere('employee_code', 'LIKE', '%' . $keyword . '%')
					->orWhere('work_email', 'LIKE', '%' . $keyword . '%')
					->orWhere('personal_email', 'LIKE', '%' . $keyword . '%')
					->orWhere('phone', 'LIKE', '%' . $keyword . '%')
					->orWhere('mobile_phone', 'LIKE', '%' . $keyword . '%');
			});
		}
		
		if ($status !== null && $status !== '' && in_array($status, [0, 1])) {
			$list->where('is_activated', $status);
		}
		
		if (is_array($departmentId) && count($departmentId) > 0) {
			$lastDepartmentId = $departmentId[count($departmentId) - 1];
			$allChildrenIds = Department::getAllChildrenIds($lastDepartmentId);
			$list->whereIn('department_id', $allChildrenIds);
		}
		
		if (!empty($positionId)) {
			$list->where('position_id', $positionId);
		}
		
		if ($employmentStatus != null && $employmentStatus != '' && $employmentStatus != 0) {
			if ($employmentStatus == 4) {
				$currentYear = Carbon::now()->year;
				$retirementAge = (integer)config('settings.retirement_age');
				$retirementAge = (!$retirementAge || $retirementAge < 10 || $retirementAge > 100) ? 60 : $retirementAge;
				$retirementBirthYear = $currentYear - ($retirementAge - 1);
				$startDate = Carbon::createFromDate($retirementBirthYear, 1, 1)->startOfDay();
				$endDate = Carbon::createFromDate($retirementBirthYear, 12, 31)->endOfDay();
				$list->working()
					->whereNotNull('date_of_birth')
					->whereBetween('date_of_birth', [$startDate->format('Y-m-d'), $endDate->format('Y-m-d')]);
			} else {
				$list->where('employment_status', $employmentStatus);
			}
		}
		
		if (!empty($employeeType)) {
			$list->where('employee_type', $employeeType);
		}
		
		$list->orderBy('id');
		
		return EmployeeShortResource::collection($list->paginate($limit));
	}
	
	public function store(Request $request)
	{
		$validator = Validator::make($request->all(), [
			// Thông tin cơ bản
			'employee_code'             => ['required', 'string', 'max:50', 'unique:employees,employee_code'],
			'last_name'                 => ['required', 'string', 'max:255'],
			'first_name'                => ['required', 'string', 'max:255'],
			'last_name_kana'            => ['required', 'string', 'max:255'],
			'first_name_kana'           => ['required', 'string', 'max:255'],
			'preferred_name'            => ['nullable', 'string', 'max:255'],
			'date_of_birth'             => ['nullable', 'date'],
			'gender'                    => ['required', 'integer', Rule::in([1, 2, 3])],
			
			// Thông tin liên lạc
			'post_code'                 => ['nullable', 'string', 'max:8', 'regex:/^\d{3}-?\d{4}$/'],
			'prefecture'                => ['nullable', 'string', 'max:255'],
			'city'                      => ['nullable', 'string', 'max:255'],
			'address'                   => ['nullable', 'string', 'max:255'],
			'building'                  => ['nullable', 'string', 'max:255'],
			'phone'                     => ['nullable', 'string', 'max:20', 'regex:/^0\d{1,4}-?\d{1,4}-?\d{4}$/'],
			'mobile_phone'              => ['nullable', 'string', 'max:20', 'regex:/^0\d0-?\d{4}-?\d{4}$/'],
			'work_email'                => ['nullable', 'email', 'max:255'],
			'personal_email'            => ['nullable', 'email', 'max:255'],
			'emergency_phone'           => ['nullable', 'string', 'max:20', 'regex:/^0\d{1,4}-?\d{1,4}-?\d{4}$/'],
			
			// Thông tin công việc
			'join_date'                 => ['required', 'date'],
			'department_id'             => ['required', 'exists:departments,id'],
			'position_id'               => ['required', 'exists:positions,id'],
			'level_id'                  => ['nullable', 'exists:levels,id'],
			'employee_type'             => ['required', 'string', Rule::in(['正社員', '派遣社員', '出向社員', '契約社員', '臨時雇用社員', '嘱託社員', '現地法人社員'])],
			'recruitment_method'        => ['nullable', 'integer', Rule::in([1, 2, 3])],
			'course'                    => ['nullable', 'string', 'max:255'],
			'working_location'          => ['nullable', 'string', 'max:255'],
			'employment_status'         => ['required', 'integer', Rule::in([1, 2, 3])],
			'resigned_date'             => ['nullable', 'date', 'required_if:employment_status,2'],
			'resigned_reason'           => ['nullable', 'integer', Rule::in([0, 1, 2, 3, 4]), 'required_if:employment_status,2'],
			
			// Transition points
			'tenure_transition_point'   => ['required', 'numeric'],
			'level_transition_point'    => ['required', 'numeric'],
			'position_transition_point' => ['required', 'numeric'],
		]);
		
		if ($validator->fails()) {
			return response()->json([
				'module' => 'employee',
				'errors' => $validator->errors()
			], 422);
		}
		
		$params = $request->all();
		$employee = Employee::create([
			// Thông tin cơ bản
			'employee_code'      => $params['employee_code'],
			'last_name'          => $params['last_name'],
			'first_name'         => $params['first_name'],
			'last_name_kana'     => $params['last_name_kana'],
			'first_name_kana'    => $params['first_name_kana'],
			'full_name'          => str_replace(" ", "", $params['last_name'] . $params['first_name']),
			'full_name_kana'     => str_replace(" ", "", $params['last_name_kana'] . $params['first_name_kana']),
			'preferred_name'     => $params['preferred_name'] ?? null,
			'date_of_birth'      => $params['date_of_birth'],
			'gender'             => $params['gender'],
			
			// Thông tin liên lạc
			'post_code'          => $params['post_code'] ?? null,
			'prefecture'         => $params['prefecture'] ?? null,
			'city'               => $params['city'] ?? null,
			'address'            => $params['address'] ?? null,
			'building'           => $params['building'] ?? null,
			'phone'              => $params['phone'] ?? null,
			'mobile_phone'       => $params['mobile_phone'] ?? null,
			'emergency_phone'    => $params['emergency_phone'] ?? null,
			'work_email'         => $params['work_email'],
			'personal_email'     => $params['personal_email'] ?? null,
			
			// Thông tin công việc
			'join_date'          => $params['join_date'],
			'department_id'      => $params['department_id'],
			'position_id'        => $params['position_id'],
			'level_id'           => $params['level_id'] ?? null,
			'employee_type'      => $params['employee_type'],
			'salary_grade'       => $params['salary_grade'] ?? null,
			'recruitment_method' => $params['recruitment_method'] ?? null,
			'course'             => $params['course'] ?? null,
			'working_location'   => $params['working_location'] ?? null,
			'employment_status'  => $params['employment_status'],
			'resigned_date'      => $params['resigned_date'] ?? null,
			'resigned_reason'    => $params['resigned_reason'] ?? null,
			
			'created_by'   => auth('api')->user()->id,
			'updated_by'   => auth('api')->user()->id,
			'is_created'   => true,
			'is_activated' => 1
		]);
		
		if (isset($params['position_data'])) {
			foreach ($params['position_data'] as $item) {
				PositionHistory::create([
					'employee_id'       => $employee->id,
					'position_id'       => $item['position_id'],
					'from_date'         => $item['from_date'],
					'to_date'           => $item['to_date']
				]);
			}
		}
		
		if (isset($params['level_data'])) {
			foreach ($params['level_data'] as $item) {
				LevelHistory::create([
					'employee_id'  => $employee->id,
					'level_id'     => $item['level_id'],
					'from_date'    => $item['from_date'],
					'to_date'      => $item['to_date'] ?? null,
					'salary_grade' => $item['salary_grade'] ?? null
				]);
			}
		}
		
		if (isset($params['leave_data'])) {
			foreach ($params['leave_data'] as $item) {
				$fromDate = Carbon::createFromFormat('Y-m-d', $item['from_date']);
				$toDate = Carbon::createFromFormat('Y-m-d', $item['to_date']);
				$totalDays = $toDate->diffInDays($fromDate) + 1;
				LeaveHistory::create([
					'employee_id'   => $employee->id,
					'leave_type_id' => $item['leave_type_id'],
					'from_date'     => $item['from_date'],
					'to_date'       => $item['to_date'],
					'total_days'    => $totalDays,
					'description'   => $item['description'] ?? null
				]);
			}
		}
		
		// Transition points
		TransitionPoint::create([
			'employee_id'     => $employee->id,
			'tenure_points'   => $params['tenure_transition_point'] ?? 0,
			'level_points'    => $params['level_transition_point'] ?? 0,
			'position_points' => $params['position_transition_point'] ?? 0,
			'created_by'      => auth('api')->user()->id
		]);
		
		return new EmployeeResource($employee);
	}
	
	public function update(Request $request, $id)
	{
		$validator = Validator::make($request->all(), [
			// Thông tin cơ bản
			'employee_code'             => ['required', 'string', 'max:50', 'unique:employees,employee_code,' . $id],
			'last_name'                 => ['required', 'string', 'max:255'],
			'first_name'                => ['required', 'string', 'max:255'],
			'last_name_kana'            => ['required', 'string', 'max:255'],
			'first_name_kana'           => ['required', 'string', 'max:255'],
			'preferred_name'            => ['nullable', 'string', 'max:255'],
			'date_of_birth'             => ['nullable', 'date'],
			'gender'                    => ['required', 'integer', Rule::in([1, 2, 3])],
			
			// Thông tin liên lạc
			'post_code'                 => ['nullable', 'string', 'max:8', 'regex:/^\d{3}-?\d{4}$/'],
			'prefecture'                => ['nullable', 'string', 'max:255'],
			'city'                      => ['nullable', 'string', 'max:255'],
			'address'                   => ['nullable', 'string', 'max:255'],
			'building'                  => ['nullable', 'string', 'max:255'],
			'phone'                     => ['nullable', 'string', 'max:20', 'regex:/^0\d{1,4}-?\d{1,4}-?\d{4}$/'],
			'mobile_phone'              => ['nullable', 'string', 'max:20', 'regex:/^0\d0-?\d{4}-?\d{4}$/'],
			'work_email'                => ['nullable', 'email', 'max:255'],
			'personal_email'            => ['nullable', 'email', 'max:255'],
			'emergency_phone'           => ['nullable', 'string', 'max:20', 'regex:/^0\d{1,4}-?\d{1,4}-?\d{4}$/'],
			
			// Thông tin công việc
			'join_date'                 => ['required', 'date'],
			'department_id'             => ['required', 'exists:departments,id'],
			'position_id'               => ['required', 'exists:positions,id'],
			'level_id'                  => ['nullable', 'exists:levels,id'],
			'employee_type'             => ['required', 'string', Rule::in(['正社員', '派遣社員', '出向社員', '契約社員', '臨時雇用社員', '嘱託社員', '現地法人社員'])],
			'recruitment_method'        => ['nullable', 'integer', Rule::in([1, 2, 3])],
			'course'                    => ['nullable', 'string', 'max:255'],
			'working_location'          => ['nullable', 'string', 'max:255'],
			'employment_status'         => ['required', 'integer', Rule::in([1, 2, 3])],
			'resigned_date'             => ['nullable', 'date', 'required_if:employment_status,2'],
			'resigned_reason'           => ['nullable', 'integer', Rule::in([0, 1, 2, 3, 4]), 'required_if:employment_status,2'],
			
			// Transition points
			'tenure_transition_point'   => ['required', 'numeric'],
			'level_transition_point'    => ['required', 'numeric'],
			'position_transition_point' => ['required', 'numeric'],
		]);
		
		if ($validator->fails()) {
			return response()->json([
				'module' => 'employee',
				'errors' => $validator->errors()
			], 422);
		}
		
		$employee = Employee::findOrFail($id);
		$params = $request->all();
		
		$newPositionHistory = null;
		if ($employee->position_id != $params['position_id']) {
			if ($employee->positionHistories->isEmpty()) {
				if ($employee->join_date) {
					$lastPositionDate = Carbon::parse($employee->join_date);
				} else {
					$lastPositionDate = Carbon::parse($employee->created_at);
				}
			} else {
				$lastPosition = $employee->positionHistories->sortByDesc('to_date')->first();
				$lastPositionDate = Carbon::parse($lastPosition->to_date)->addDay();
			}
			$newPositionHistory = [
				'employee_id' => $employee->id,
				'position_id' => $employee->position_id,
				'from_date'   => $lastPositionDate->format('Y-m-d'),
				'to_date'     => Carbon::now()->subDay()->format('Y-m-d'),
			];
		}
		
		$newLevelHistory = null;
		$newSalaryGrade = $params['salary_grade'] ?? $employee->salary_grade;
		if ($employee->level_id != $params['level_id'] || $employee->salary_grade != $newSalaryGrade) {
			if ($employee->levelHistories->isEmpty()) {
				if ($employee->join_date) {
					$lastLevelDate = Carbon::parse($employee->join_date);
				} else {
					$lastLevelDate = Carbon::parse($employee->created_at);
				}
			} else {
				$lastLevel = $employee->levelHistories->sortByDesc('to_date')->first();
				$lastLevelDate = Carbon::parse($lastLevel->to_date)->addDay();
			}
			$newLevelHistory = [
				'employee_id'  => $employee->id,
				'level_id'     => $employee->level_id,
				'from_date'    => $lastLevelDate->format('Y-m-d'),
				'to_date'      => Carbon::now()->subDay()->format('Y-m-d'),
				'salary_grade' => $employee->salary_grade ?? null,
			];
		}
		
		$employee->update([
			// Thông tin cơ bản
			'last_name'          => $params['last_name'],
			'first_name'         => $params['first_name'],
			'last_name_kana'     => $params['last_name_kana'],
			'first_name_kana'    => $params['first_name_kana'],
			'full_name'          => str_replace(" ", "", $params['last_name'] . $params['first_name']),
			'full_name_kana'     => str_replace(" ", "", $params['last_name_kana'] . $params['first_name_kana']),
			'preferred_name'     => $params['preferred_name'] ?? null,
			'date_of_birth'      => $params['date_of_birth'],
			'gender'             => $params['gender'],
			
			// Thông tin liên lạc
			'post_code'          => $params['post_code'] ?? null,
			'prefecture'         => $params['prefecture'] ?? null,
			'city'               => $params['city'] ?? null,
			'address'            => $params['address'] ?? null,
			'building'           => $params['building'] ?? null,
			'phone'              => $params['phone'] ?? null,
			'mobile_phone'       => $params['mobile_phone'] ?? null,
			'emergency_phone'    => $params['emergency_phone'] ?? null,
			'work_email'         => $params['work_email'],
			'personal_email'     => $params['personal_email'] ?? null,
			
			// Thông tin công việc
			'join_date'          => $params['join_date'],
			'department_id'      => $params['department_id'],
			'position_id'        => $params['position_id'],
			'level_id'           => $params['level_id'] ?? null,
			'employee_type'      => $params['employee_type'],
			'salary_grade'       => $params['salary_grade'] ?? null,
			'recruitment_method' => $params['recruitment_method'] ?? null,
			'course'             => $params['course'] ?? null,
			'working_location'   => $params['working_location'] ?? null,
			'employment_status'  => $params['employment_status'],
			'resigned_date'      => ($params['employment_status'] == 2 && $params['resigned_date']) ? $params['resigned_date'] : null,
			'resigned_reason'    => $params['employment_status'] == 2 ? $params['resigned_reason'] : null,
			
			'is_created'   => true,
			'updated_by'   => auth('api')->user()->id,
			'is_activated' => 1,
		]);
		
		if (in_array($params['employment_status'], [1, 3])) {
			$employee->update([
				'resigned_date'   => null,
				'resigned_reason' => null,
			]);
		} else {
			if ($params['resigned_date'] == null || $params['resigned_date'] == "") {
				$employee->update(['resigned_date' => Carbon::now()->format('Y-m-d')]);
			}
		}
		
		if (isset($params['position_data'])) {
			PositionHistory::where('employee_id', $employee->id)->delete();
			foreach ($params['position_data'] as $item) {
				PositionHistory::create([
					'employee_id'       => $employee->id,
					'position_id'       => $item['position_id'],
					'from_date'         => $item['from_date'],
					'to_date'           => $item['to_date']
				]);
			}
		}
		if ($newPositionHistory) PositionHistory::create($newPositionHistory);
		
		if (isset($params['level_data'])) {
			LevelHistory::where('employee_id', $employee->id)->delete();
			foreach ($params['level_data'] as $item) {
				LevelHistory::create([
					'employee_id'  => $employee->id,
					'level_id'     => $item['level_id'],
					'from_date'    => $item['from_date'],
					'to_date'      => $item['to_date'] ?? null,
					'salary_grade' => $item['salary_grade'] ?? null
				]);
			}
		}
		if ($newLevelHistory) LevelHistory::create($newLevelHistory);
		
		if (isset($params['leave_data'])) {
			LeaveHistory::where('employee_id', $employee->id)->delete();
			foreach ($params['leave_data'] as $item) {
				$fromDate = Carbon::createFromFormat('Y-m-d', $item['from_date']);
				$toDate = Carbon::createFromFormat('Y-m-d', $item['to_date']);
				$totalDays = $toDate->diffInDays($fromDate) + 1;
				LeaveHistory::create([
					'employee_id'   => $employee->id,
					'leave_type_id' => $item['leave_type_id'],
					'from_date'     => $item['from_date'],
					'to_date'       => $item['to_date'],
					'total_days'    => $totalDays,
					'description'   => $item['description'] ?? null
				]);
			}
		}
		
		// Transition points
		$transitionPoint = TransitionPoint::where('employee_id', $employee->id)->first();
		if (!$transitionPoint) {
			TransitionPoint::create([
				'employee_id'     => $employee->id,
				'tenure_points'   => $params['tenure_transition_point'],
				'level_points'    => $params['level_transition_point'],
				'position_points' => $params['position_transition_point'],
				'created_by'      => auth('api')->user()->id
			]);
		} else {
			$transitionPoint->update([
				'tenure_points'   => $params['tenure_transition_point'],
				'level_points'    => $params['level_transition_point'],
				'position_points' => $params['position_transition_point'],
				'created_by'      => auth('api')->user()->id
			]);
		}
		
		return response()->json(null, 204);
	}
	
	public function show($id)
	{
		$employee = Employee::with(['department', 'position', 'level', 'positionHistories', 'levelHistories', 'leaveHistories', 'transitionPoint'])
			->findOrFail($id);
		
		return new EmployeeDetailResource($employee);
	}
	
	public function destroy($id)
	{
		$employee = Employee::findOrFail($id);
		$employee->delete();
		return response()->json(null, 204);
	}
	
	public function destroyMultiple(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'ids' => 'required|array'
		]);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$listIds = $request->get('ids', []);
		Employee::whereIn('id', $listIds)->delete();
		return response()->json(null, 204);
	}
	
	public function activateMultiple(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'ids' => 'required|array'
		]);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$listIds = $request->get('ids', []);
		Employee::whereIn('id', $listIds)->update(['is_activated' => true]);
		return response()->json(null, 204);
	}
	
	public function deactivateMultiple(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'ids' => 'required|array'
		]);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 403);
		}
		
		$listIds = $request->get('ids', []);
		Employee::whereIn('id', $listIds)->update(['is_activated' => false]);
		return response()->json(null, 204);
	}
	
	public function export(Request $request)
	{
		try {
			$csvPath = public_path('csv');
			if (!File::exists($csvPath)) {
				File::makeDirectory($csvPath, 0777, true);
			}
			
			$timestamp = date('YmdHis');
			$originalName = "カオナビ　基本情報_{$timestamp} GO様.csv";
			$encodedName = md5($originalName . $timestamp) . '.csv';
			$fullPath = $csvPath . '/' . $encodedName;
			
			$handle = fopen($fullPath, 'w');
			fprintf($handle, chr(0xEF) . chr(0xBB) . chr(0xBF));
			
			fputcsv($handle, [
				'社員番号',      // Mã nhân viên
				'氏名',         // Họ tên
				'フリガナ',      // Furigana
				'所属コード',    // Mã phòng ban
				'(所属名1)',    // Tên phòng ban cấp 1
				'(所属名2)',    // Tên phòng ban cấp 2
				'(所属名3)',    // Tên phòng ban cấp 3
				'(所属名4)',    // Tên phòng ban cấp 4
				'本名',         // Tên thật
				'役職',         // Chức vụ
				'性別',         // Giới tính
				'生年月日',     // Ngày sinh
				'年齢',         // Tuổi
				'従業員区分',    // Phân loại nhân viên
				'採用区分',      // Hình thức tuyển dụng
				'コース',       // Khóa/Course
				'入社日',       // Ngày vào công ty
				'退職日',       // Ngày nghỉ việc
				'勤続年数',     // Số năm làm việc
				'等級',         // Cấp bậc
				'号俸',         // Bậc lương
				'勤務地',       // Nơi làm việc
				'メール',       // Email
				'(最終更新ユーザー)', // Người cập nhật cuối cùng
				'(最終更新日時)'     // Thời gian cập nhật cuối cùng
			]);
			
			Employee::with(['department', 'position'])
				->chunk(100, function ($employees) use ($handle) {
					foreach ($employees as $employee) {
						// Xử lý giới tính
						$gender = '';
						switch ($employee->gender) {
							case 1:
								$gender = '男性';
								break;   // Nam
							case 2:
								$gender = '女性';
								break;   // Nữ
							case 3:
								$gender = 'その他';
								break; // Khác
						}
						
						// Xử lý phân loại nhân viên
						$employeeType = '';
						switch ($employee->employee_type) {
							case 'regular':
								$employeeType = '正社員';
								break;
							case 'contract':
								$employeeType = '契約社員';
								break;
							case 'part_time':
								$employeeType = 'パート';
								break;
						}
						
						// Xử lý department levels
						$deptLevels = ['', '', '', ''];
						if ($employee->department) {
							$dept = Department::with('parent')->find($employee->department->id);
							$parentDepts = [];
							$currentDept = $dept;
							while ($currentDept) {
								array_unshift($parentDepts, [
									'code' => $currentDept->code,
									'name' => $currentDept->name
								]);
								$currentDept = $currentDept->parent;
							}
							$totalLevels = count($parentDepts);
							$startIndex = max(0, $totalLevels - 4);
							for ($i = 0; $i < min(4, $totalLevels); $i++) {
								$deptLevels[$i] = $parentDepts[$startIndex + $i]['name'];
							}
						}
						
						// Xử lý position (để trống nếu là nhân viên thông thường)
						$position = '';
						if ($employee->position && $employee->position->code !== 'staff') {
							$position = $employee->position->name;
						}
						
						// Format dates
						$birthDate = $employee->date_of_birth ? date('Y/m/d', strtotime($employee->date_of_birth)) : '';
						$joinDate = $employee->join_date ? date('Y/m/d', strtotime($employee->join_date)) : '';
						$resignedDate = $employee->resigned_date ? date('Y/m/d', strtotime($employee->resigned_date)) : '';
						
						// Tính tuổi
						$age = '';
						if ($employee->date_of_birth) {
							$age = Carbon::parse($employee->date_of_birth)->age;
						}
						
						// Tính số năm làm việc
						$yearsOfService = '';
						if ($employee->join_date) {
							$endDate = $employee->resigned_date ? Carbon::parse($employee->resigned_date) : Carbon::now();
							$yearsOfService = Carbon::parse($employee->join_date)->diffInYears($endDate);
						}
						
						fputcsv($handle, [
							$employee->employee_code,
							$employee->last_name . ' ' . $employee->first_name,
							$employee->last_name_kana . ' ' . $employee->first_name_kana,
							$employee->department ? $employee->department->code : '',
							$deptLevels[0],
							$deptLevels[1],
							$deptLevels[2],
							$deptLevels[3],
							$employee->preferred_name,
							$position,
							$gender,
							$birthDate,
							$age,
							$employeeType,
							$employee->recruitment_method,
							$employee->course,
							$joinDate,
							$resignedDate,
							$yearsOfService,
							$employee->level_id,
							$employee->salary_grade,
							$employee->working_location,
							$employee->work_email,
							$employee->updated_by,
							$employee->updated_at ? date('Y/m/d H:i:s', strtotime($employee->updated_at)) : ''
						]);
					}
				});
			
			fclose($handle);
			
			Cache::put('csv_export_' . $encodedName, $originalName, now()->addHours(1));
			
			return response()->json([
				'status' => 'success',
				'data'   => [
					'encoded_name'  => $encodedName,
					'original_name' => $originalName,
					'download_url'  => url('csv/' . $encodedName)
				]
			]);
		} catch (\Exception $e) {
			return response()->json([
				'status'  => 'error',
				'message' => $e->getMessage()
			], 500);
		}
	}
	
	public function import(Request $request)
	{
		$validator = Validator::make($request->all(), [
			'name' => ['required', 'string', 'max:255'],
			'size' => ['required', 'string', 'max:255'],
			'type' => ['required', 'string', 'max:255', 'in:.csv,text/csv,application/vnd.ms-excel'],
		]);
		
		$params = $request->all();
		$csvData = [];
		
		// Read CSV
		$this->validateAndReadCsv($validator, $params, $csvData);
		
		if ($validator->fails()) {
			return response()->json(['errors' => $validator->errors()], 422);
		}
		
		// Import Data
		try {
			array_shift($csvData);
			DB::beginTransaction();
			
			$departments = $this->collectDepartments($csvData);
			$processedDepartments = $this->importDepartments($departments);
			
			foreach ($csvData as $index => $row) {
				try {
					if (count($row) < 10) {
						Log::warning("Row {$index} has insufficient columns: " . count($row));
						continue;
					}
					
					$positionId = $this->positionImport($row);
					$this->employeeImport($row, $processedDepartments, $positionId);
				} catch (\Exception $e) {
					Log::error("Error importing row {$index}: " . $e->getMessage());
					continue;
				}
			}
			
			DB::commit();
			return response()->json(['message' => 'Import successful'], 200);
		} catch (\Exception $e) {
			DB::rollBack();
			return response()->json(['error' => 'Import failed: ' . $e->getMessage()], 422);
		}
	}
	
	private function employeeImport($row, $processedDepartments, $positionId)
	{
		$names = $this->splitName($row[1]); // 氏名
		$kanaNames = $this->splitKanaName($row[2]); // フリガナ
		
		try {
			$deptCode = $row[3]; // 所属コード
			$departmentId = null;
			if (!empty($deptCode)) {
				$departmentId = $processedDepartments[$deptCode] ?? // Cấp 4 (mã đầy đủ)
					$processedDepartments[substr($deptCode, 0, 8) . '000'] ?? // Cấp 3
					$processedDepartments[substr($deptCode, 0, 5) . '000000'] ?? // Cấp 2
					$processedDepartments[substr($deptCode, 0, 2) . '000000000'] ?? // Cấp 1
					null;
			}
			
			if (!$departmentId) {
				$defaultDept = Department::firstOrCreate(
					['code' => '000000000000'],
					[
						'name'         => '未所属', // Chưa phân công
						'is_activated' => true
					]
				);
				$departmentId = $defaultDept->id;
			}
			
			if ($row[13] != null && $row[13] != "") {
				logger($row[13]);
			}
			
			$levelId = null;
			if (trim($row[19]) != null && trim($row[19]) != "") {
				$level = Level::where('parent_id', '!=', 0)->where('name', $row[19])->first();
				if (!$level) {
					do {
						$levelCode = str_pad(rand(20, 99), 4, "0", STR_PAD_LEFT);
						$checkLevelCode = Level::where('parent_id', '!=', 0)->where('code', $levelCode)->count();
					} while ($checkLevelCode > 0);
					
					$level = Level::create([
						'code'       => $levelCode,
						'name'       => $row[19],
						'points'     => 0,
						'parent_id'  => 36,
						'created_by' => 1
					]);
				}
				$levelId = $level->id;
			}
			
			$employeeData = [
				// Thông tin cơ bản
				'employee_code'      => $row[0],
				'last_name'          => $names['last_name'],
				'first_name'         => $names['first_name'],
				'last_name_kana'     => $kanaNames['last_name_kana'],
				'first_name_kana'    => $kanaNames['first_name_kana'],
				'full_name'          => str_replace(" ", "", $row[1]),
				'full_name_kana'     => str_replace(" ", "", $row[2]),
				'preferred_name'     => $row[1], // Tên thường gọi là tên trong CSV
				'date_of_birth'      => trim($row[11]) != "" ? Carbon::parse(trim($row[11])) : null, // 生年月日
				'gender'             => $this->genders[$row[10]] ?? 3, // 性別
				
				// Thông tin công việc
				'join_date'          => Carbon::parse($row[16]), // 入社日
				'department_id'      => $departmentId,
				'position_id'        => $positionId,
				'employee_type'      => $this->mapEmployeeType($row[13]), // 従業員区分
				'recruitment_method' => $this->recruitmentMethods[$row[14]] ?? null, // 採用区分
				'course'             => $this->courses[$row[15]] ?? null, // コース
				'level_id'           => $levelId, // 等級
				'salary_grade'       => intval($row[20]) ?? null, // 号俸
				'working_location'   => $row[21], // 勤務地
				'work_email'         => trim($row[22]) != '' ? trim($row[22]) : null, // メール
				
				// Thông tin nghỉ việc
				'resigned_date'      => !empty($row[17]) ? Carbon::parse($row[17]) : null, // 退職日
				'employment_status'  => !empty($row[17]) ? 2 : 1, // Nếu có ngày nghỉ việc thì status = 2
				
				// System fields
				'is_created'         => false,
				'updated_by'         => auth('api')->user()->id,
				'is_activated'       => true
			];
			
			// Tìm employee kể cả đã bị soft-delete
			$employee = Employee::withTrashed()->where('employee_code', $row[0])->first();
			if ($employee) {
				// Cập nhật thông tin mới nhất
				$employee->update($employeeData);

				// Nếu đã bị soft-delete, restore employee và các related records
				if ($employee->trashed()) {
					$employee->restore();

					// Restore các related records
					$employee->positionHistories()->withTrashed()->restore();
					$employee->levelHistories()->withTrashed()->restore();
					$employee->leaveHistories()->withTrashed()->restore();
					$employee->transitionPoint()->withTrashed()->restore();
					$employee->retirementFund()->withTrashed()->restore();
					$employee->severancePayment()->withTrashed()->restore();

					Log::info("Employee {$row[0]} restored from soft-delete with related records.");
				}
			} else {
				$employeeData['created_by'] = auth('api')->user()->id;
				Employee::create($employeeData);
			}
		} catch (\Exception $e) {
			Log::error("Error importing employee {$row[0]}: " . $e->getMessage());
		}
	}
	
	private function positionImport($row)
	{
		if (count($row) < 10) return;
		
		$positionName = trim($row[9]); // 役職
		if (empty($positionName)) {
			$positionName = 'なし';
		}
		
		$position = Position::where('name', $positionName)->first();
		if (!$position) {
			do {
				$positionCode = rand(1, 98);
				$checkCode = Position::where('code', $positionCode)->count();
			} while ($checkCode > 0);
			
			$position = Position::create([
				'code'         => $positionCode,
				'name'         => $positionName,
				'point_value'  => 0,
				'is_activated' => true
			]);
		}
		
		return $position->id;
	}
	
	private function getPositionPointValue($positionName)
	{
		$pointValues = [
			// C-Level & Board Members
			'代表取締役社長兼社長執行役員' => 180.00,  // Chủ tịch kiêm Tổng giám đốc điều hành
			'代表取締役'                   => 160.00,                    // Chủ tịch HĐQT
			'取締役会長'                   => 140.00,                    // Chủ tịch điều hành
			'取締役社長'                   => 120.00,                    // Tổng giám đốc
			
			// Executive Officers
			'取締役兼執行役員'             => 100.00,            // Giám đốc kiêm chấp hành
			'執行役員(雇用)'               => 90.00,               // Chấp hành viên
			'執行役員'                     => 90.00,                     // Chấp hành viên
			
			// Directors & Advisors
			'非常勤取締役'                 => 85.00,                 // Giám đốc không chuyên trách
			'非常勤監査役'                 => 80.00,                 // Kiểm soát viên không chuyên trách
			'非常勤顧問'                   => 75.00,                   // Cố vấn không chuyên trách
			'顧問'                         => 75.00,                   // Cố vấn chuyên trách
			
			// Management
			'グループ長'                   => 70.00,                   // Trưởng nhóm
			'グループ長代理'               => 65.00,               // Phó trưởng nhóm
			'チーム長'                     => 60.00,                     // Trưởng team
			'担当チーム長'                 => 55.00,                 // Trưởng team phụ trách
			
			// Team Members
			'リーダー'                     => 50.00,                     // Leader
			'サブリーダー'                 => 47.00,                 // Sub-leader
			'主務'                         => 47.00,                 // Sub-leader
			'スタッフ'                     => 45.00,                     // Nhân viên
			
			// Specialists
			'参与'                         => 40.00,                         // Tham vấn
			'参事'                         => 35.00,                         // Tham sự
			'マイスター'                   => 30.00,                   // Chuyên gia
			'エキスパート'                 => 25.00,                 // Chuyên viên
			
			// Others
			'一般社員'                     => 45.00,                     // Nhân viên thông thường
			'契約社員'                     => 40.00,                     // Nhân viên hợp đồng
			'パート社員'                   => 35.00                    // Nhân viên bán thời gian
		];
		
		if (!isset($pointValues[$positionName])) Log::warning("Position not defined in point values: {$positionName}");
		
		return $pointValues[$positionName] ?? 0.00;
	}
	
	private function validateAndReadCsv($validator, $params, &$csvData)
	{
		$validator->after(function ($validator) use ($params, &$csvData) {
			try {
				$filePath = public_path('uploads/files/' . $params['name']);
				if (!file_exists($filePath)) {
					$validator->errors()->add('file', 'CSV file does not exist.');
					return;
				}
				
				$content = file_get_contents($filePath);
				$content = str_replace("\xEF\xBB\xBF", '', $content);
				
				$csvData = array_map(function ($line) {
					return str_getcsv($line);
				}, explode("\n", $content));
				
				$csvData = array_filter($csvData, function ($row) {
					return !empty(array_filter($row));
				});
				
				$csvData = array_values($csvData);
				
				if (empty($csvData)) {
					$validator->errors()->add('file', 'Empty CSV file');
					return;
				}
				
				$this->validateCsvHeaders($validator, $csvData[0]);
			} catch (\Exception $e) {
				Log::error('CSV Read Error: ' . $e->getMessage());
				$validator->errors()->add('file', 'Cannot read CSV file: ' . $e->getMessage());
			}
		});
	}
	
	private function validateCsvHeaders($validator, $headers)
	{
		$requiredHeaders = [
			'社員番号',      // Mã nhân viên
			'氏名',         // Họ tên
			'フリガナ',      // Furigana (cách đọc tên)
			'所属コード',    // Mã phòng ban
			'(所属名1)',    // Tên phòng ban cấp 1
			'(所属名2)',    // Tên phòng ban cấp 2
			'(所属名3)',    // Tên phòng ban cấp 3
			'(所属名4)',    // Tên phòng ban cấp 4
			'本名',         // Tên thật
			'役職',         // Chức vụ
			'性別',         // Giới tính
			'生年月日',     // Ngày sinh
			'年齢',         // Tuổi
			'従業員区分',    // Phân loại nhân viên
			'採用区分',      // Hình thức tuyển dụng
			'コース',       // Khóa/Course
			'入社日',       // Ngày vào công ty
			'退職日',       // Ngày nghỉ việc
			'勤続年数',     // Số năm làm việc
			'等級',         // Cấp bậc
			'号俸',         // Bậc lương
			'勤務地',       // Nơi làm việc
			'メール',       // Email
			'(最終更新ユーザー)', // Người cập nhật cuối cùng
			'(最終更新日時)'     // Thời gian cập nhật cuối cùng
		];
		
		$headers = array_map(function ($header) {
			$header = str_replace("\xEF\xBB\xBF", '', $header);
			return trim($header);
		}, $headers);
		
		foreach ($requiredHeaders as $required) {
			if (!in_array($required, $headers, true)) {
				$validator->errors()->add(
					'file',
					"CSV file missing required column: {$required}"
				);
			}
		}
	}
	
	private function splitName($fullName)
	{
		$parts = explode(' ', trim($fullName));
		$firstName = array_pop($parts);
		$lastName = implode(' ', $parts);
		
		return [
			'first_name' => $firstName,
			'last_name'  => $lastName
		];
	}
	
	private function splitKanaName($fullKanaName)
	{
		$parts = explode(' ', trim($fullKanaName));
		$firstNameKana = array_pop($parts);
		$lastNameKana = implode(' ', $parts);
		
		return [
			'first_name_kana' => $firstNameKana,
			'last_name_kana'  => $lastNameKana
		];
	}
	
	private function mapEmployeeType($type)
	{
		$mapping = [
			'正社員'       => '0',
			'派遣社員'     => '1',
			'出向社員'     => '2',
			'契約社員'     => '3',
			'臨時雇用社員' => '4',
			'嘱託社員'     => '5',
			'現地法人社員' => '6',
		];
		return $mapping[$type] ?? '0';
	}
	
	private function mapLevelType($level)
	{
		return $this->levelTypes[$level] ?? null;
	}
	
	private function collectDepartments($rows)
	{
		$departments = [];
		
		foreach ($rows as $row) {
			if (count($row) < 8) continue;
			
			$fullCode = trim($row[3]); // Mã phòng ban đầy đủ
			if (empty($fullCode) || strlen($fullCode) != 11) continue;
			
			$deptNames = [
				1 => trim($row[4]), // Cấp 1
				2 => trim($row[5]), // Cấp 2
				3 => trim($row[6]), // Cấp 3
				4 => trim($row[7])  // Cấp 4
			];
			
			$deptCodes = [
				1 => substr($fullCode, 0, 2) . '000000000',  // 2 số đầu + 9 số 0
				2 => substr($fullCode, 0, 5) . '000000',     // 5 số đầu + 6 số 0
				3 => substr($fullCode, 0, 8) . '000',        // 8 số đầu + 3 số 0
				4 => $fullCode                               // Mã đầy đủ
			];
			
			$parentCode = null;
			for ($level = 1; $level <= 4; $level++) {
				$deptName = $deptNames[$level];
				if (empty($deptName)) continue;
				$currentCode = $deptCodes[$level];
				if (!isset($departments[$currentCode])) {
					$departments[$currentCode] = [
						'name'        => $deptName,
						'code'        => $currentCode,
						'level'       => $level,
						'parent_code' => $parentCode
					];
				}
				$parentCode = $currentCode;
			}
		}
		
		return $departments;
	}
	
	private function importDepartments($departments)
	{
		$processedDepts = [];
		uasort($departments, function ($a, $b) {
			return $a['level'] <=> $b['level'];
		});
		foreach ($departments as $code => $dept) {
			try {
				$parentId = null;
				if ($dept['parent_code']) {
					$parentId = $processedDepts[$dept['parent_code']] ?? null;
				}
				$department = Department::firstOrCreate(
					['code' => $code],
					[
						'name'         => $dept['name'],
						'parent_id'    => $parentId,
						'is_activated' => 1
					]
				);
				$processedDepts[$code] = $department->id;
			} catch (\Exception $e) {
				Log::error("Error importing department", [
					'code'  => $code,
					'error' => $e->getMessage()
				]);
			}
		}
		
		return $processedDepts;
	}
}