<?php

namespace App\Services\Design;

use App\Models\Design\DesignModel;
use App\Services\Service;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ModelService extends Service
{
    /** 목록 */
    public function list(string $q = '', int $page = 1, int $size = 20): LengthAwarePaginator
    {
        $tenantId = $this->tenantId();

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

        if ($q !== '') {
            $query->where(function ($w) use ($q) {
                $w->where('code', 'like', "%{$q}%")
                    ->orWhere('name', 'like', "%{$q}%")
                    ->orWhere('description', 'like', "%{$q}%");
            });
        }

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

    /** 생성 */
    public function create(array $data): DesignModel
    {
        $tenantId = $this->tenantId();

        $exists = DesignModel::query()
            ->where('tenant_id', $tenantId)
            ->where('code', $data['code'])
            ->exists();

        if ($exists) {
            throw ValidationException::withMessages(['code' => __('error.duplicate')]);
        }

        return DB::transaction(function () use ($tenantId, $data) {
            $payload = array_merge($data, ['tenant_id' => $tenantId]);

            return DesignModel::create($payload);
        });
    }

    /** 단건 */
    public function find(int $id): DesignModel
    {
        $tenantId = $this->tenantId();
        $model = DesignModel::query()
            ->where('tenant_id', $tenantId)
            ->with(['versions' => fn ($q) => $q->orderBy('version_no')])
            ->find($id);

        if (! $model) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        return $model;
    }

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

        $model = DesignModel::query()
            ->where('tenant_id', $tenantId)
            ->find($id);

        if (! $model) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        if (isset($data['code']) && $data['code'] !== $model->code) {
            $dup = DesignModel::query()
                ->where('tenant_id', $tenantId)
                ->where('code', $data['code'])
                ->exists();
            if ($dup) {
                throw ValidationException::withMessages(['code' => __('error.duplicate')]);
            }
        }

        $model->fill($data);
        $model->save();

        return $model;
    }

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

        $model = DesignModel::query()
            ->where('tenant_id', $tenantId)
            ->find($id);

        if (! $model) {
            throw new NotFoundHttpException(__('error.not_found'));
        }

        $model->delete();
    }
}
