<?php

namespace App\Services;

use App\Models\Commons\Classification;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ClassificationService extends Service
{
    /** 목록(검색/페이징) */
    public function index(array $params)
    {
        $tenantId = $this->tenantId();

        $page = (int) ($params['page'] ?? 1);
        $size = (int) ($params['size'] ?? 20);
        $q = trim((string) ($params['q'] ?? ''));
        $group = $params['group'] ?? null;
        $only = $params['only_active'] ?? null;

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

        if ($q !== '') {
            $query->where(function ($w) use ($q) {
                $w->where('name', 'like', "%{$q}%")
                    ->orWhere('code', 'like', "%{$q}%");
            });
        }
        if (! is_null($group) && $group !== '') {
            $query->where('group', $group);
        }
        if (! is_null($only)) {
            $query->where('is_active', (int) (bool) $only);
        }

        $query->orderBy('group')->orderBy('code')->orderBy('id');

        return $query->paginate($size, ['*'], 'page', $page);
    }

    /** 단건 */
    public function show(int $id)
    {
        $tenantId = $this->tenantId();
        $row = Classification::where('tenant_id', $tenantId)->find($id);
        if (! $row) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        return $row;
    }

    /** 생성 */
    public function store(array $params)
    {
        $tenantId = $this->tenantId();
        $uid = $this->apiUserId();

        $v = Validator::make($params, [
            'group' => 'required|string|max:50',
            'code' => 'required|string|max:50',
            'name' => 'required|string|max:100',
            'is_active' => 'nullable|boolean',
        ]);
        if ($v->fails()) {
            throw new BadRequestHttpException($v->errors()->first());
        }

        // 그룹 내 코드 중복 체크(tenant 기준)
        $data = $v->validated();
        $exists = Classification::where('tenant_id', $tenantId)
            ->where('group', $data['group'])
            ->where('code', $data['code'])
            ->exists();
        if ($exists) {
            throw new BadRequestHttpException(__('validation.unique', ['attribute' => 'code']));
        }

        $data['tenant_id'] = $tenantId;
        $data['is_active'] = (int) ($data['is_active'] ?? 1);

        return Classification::create($data);
    }

    /** 수정 */
    public function update(int $id, array $params)
    {
        $tenantId = $this->tenantId();

        $row = Classification::where('tenant_id', $tenantId)->find($id);
        if (! $row) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $v = Validator::make($params, [
            'group' => 'sometimes|required|string|max:50',
            'code' => 'sometimes|required|string|max:50',
            'name' => 'sometimes|required|string|max:100',
            'is_active' => 'nullable|boolean',
        ]);
        if ($v->fails()) {
            throw new BadRequestHttpException($v->errors()->first());
        }

        $payload = $v->validated();

        // group 또는 code 변경 시 유니크 검사
        $newGroup = $payload['group'] ?? $row->group;
        $newCode = $payload['code'] ?? $row->code;
        $dupe = Classification::where('tenant_id', $tenantId)
            ->where('group', $newGroup)
            ->where('code', $newCode)
            ->where('id', '!=', $row->id)
            ->exists();
        if ($dupe) {
            throw new BadRequestHttpException(__('validation.unique', ['attribute' => 'code']));
        }

        $row->update($payload);

        return $row->refresh();
    }

    /** 삭제(soft) */
    public function destroy(int $id)
    {
        $tenantId = $this->tenantId();

        $row = Classification::where('tenant_id', $tenantId)->find($id);
        if (! $row) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $row->delete();

        return 'success';
    }
}
