<?php

namespace App\Services;

use App\Models\Tenants\Department;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Collection;

class DepartmentService
{
    /**
     * 부서 목록 조회 (페이지네이션)
     */
    public function getDepartments(array $filters = [], int $perPage = 15): LengthAwarePaginator
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::query()->withTrashed()->with('parent');

        // Tenant 필터링 (선택된 경우에만)
        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        // Soft Delete 필터
        if (isset($filters['trashed'])) {
            if ($filters['trashed'] === 'only') {
                $query->onlyTrashed();
            } elseif ($filters['trashed'] === 'with') {
                $query->withTrashed();
            }
        }

        // 검색 필터
        if (! empty($filters['search'])) {
            $search = $filters['search'];
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('code', 'like', "%{$search}%")
                    ->orWhere('description', 'like', "%{$search}%");
            });
        }

        // 활성 상태 필터
        if (isset($filters['is_active'])) {
            $query->where('is_active', $filters['is_active']);
        }

        // 정렬
        $sortBy = $filters['sort_by'] ?? 'sort_order';
        $sortDirection = $filters['sort_direction'] ?? 'asc';
        $query->orderBy($sortBy, $sortDirection);

        return $query->paginate($perPage);
    }

    /**
     * 특정 부서 조회
     */
    public function getDepartmentById(int $id): ?Department
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::query()->with(['parent', 'children']);

        // Tenant 필터링 (선택된 경우에만)
        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        return $query->find($id);
    }

    /**
     * 부서 생성
     */
    public function createDepartment(array $data): Department
    {
        $tenantId = session('selected_tenant_id');

        $department = Department::create([
            'tenant_id' => $tenantId,
            'parent_id' => $data['parent_id'] ?? null,
            'code' => $data['code'],
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'is_active' => $data['is_active'] ?? true,
            'sort_order' => $data['sort_order'] ?? 0,
            'created_by' => auth()->id(),
        ]);

        return $department->fresh(['parent']);
    }

    /**
     * 부서 수정
     */
    public function updateDepartment(int $id, array $data): bool
    {
        $department = $this->getDepartmentById($id);

        if (! $department) {
            return false;
        }

        // 자기 자신을 상위 부서로 설정하는 것 방지
        if (isset($data['parent_id']) && $data['parent_id'] == $id) {
            return false;
        }

        $updated = $department->update([
            'parent_id' => $data['parent_id'] ?? $department->parent_id,
            'code' => $data['code'] ?? $department->code,
            'name' => $data['name'] ?? $department->name,
            'description' => $data['description'] ?? $department->description,
            'is_active' => $data['is_active'] ?? $department->is_active,
            'sort_order' => $data['sort_order'] ?? $department->sort_order,
            'updated_by' => auth()->id(),
        ]);

        return $updated;
    }

    /**
     * 부서 삭제 (Soft Delete)
     */
    public function deleteDepartment(int $id): bool
    {
        $department = $this->getDepartmentById($id);

        if (! $department) {
            return false;
        }

        // 하위 부서가 있는 경우 삭제 불가
        if ($department->children()->count() > 0) {
            return false;
        }

        $department->deleted_by = auth()->id();
        $department->save();

        return $department->delete();
    }

    /**
     * 부서 복원
     */
    public function restoreDepartment(int $id): bool
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::onlyTrashed();

        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        $department = $query->find($id);

        if (! $department) {
            return false;
        }

        return $department->restore();
    }

    /**
     * 부서 영구 삭제
     */
    public function forceDeleteDepartment(int $id): bool
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::withTrashed();

        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        $department = $query->find($id);

        if (! $department) {
            return false;
        }

        // 하위 부서가 있는 경우 삭제 불가
        if ($department->children()->count() > 0) {
            return false;
        }

        return $department->forceDelete();
    }

    /**
     * 부서 코드 중복 체크
     */
    public function isCodeExists(string $code, ?int $excludeId = null): bool
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::where('tenant_id', $tenantId)
            ->where('code', $code);

        if ($excludeId) {
            $query->where('id', '!=', $excludeId);
        }

        return $query->exists();
    }

    /**
     * 활성 부서 목록 (드롭다운용)
     */
    public function getActiveDepartments(): Collection
    {
        $tenantId = session('selected_tenant_id');

        $query = Department::query()->where('is_active', true);

        // Tenant 필터링 (선택된 경우에만)
        if ($tenantId) {
            $query->where('tenant_id', $tenantId);
        }

        return $query->orderBy('sort_order')->orderBy('name')->get(['id', 'parent_id', 'code', 'name']);
    }

    /**
     * 부서 통계
     */
    public function getDepartmentStats(): array
    {
        $tenantId = session('selected_tenant_id');

        $baseQuery = Department::query();

        // Tenant 필터링 (선택된 경우에만)
        if ($tenantId) {
            $baseQuery->where('tenant_id', $tenantId);
        }

        return [
            'total' => (clone $baseQuery)->count(),
            'active' => (clone $baseQuery)->where('is_active', true)->count(),
            'inactive' => (clone $baseQuery)->where('is_active', false)->count(),
        ];
    }
}
