<?php

namespace App\Controllers\Api;

use App\Models\SiteModel;
use App\Models\TurbineModel;

class Turbines extends BaseApiController
{
    public function index()
    {
        if ($response = $this->requireAnyApiScope(['turbines:read', 'meters:read'])) {
            return $response;
        }

        $builder = (new TurbineModel())
            ->withRelations()
            ->where('sites.organization_id', $this->apiOrganizationId());

        $siteId = (int) ($this->request->getGet('site_id') ?? 0);
        if ($siteId > 0) {
            $builder->where('turbines.site_id', $siteId);
        }

        return $this->respondOk(
            $builder->orderBy('sites.name', 'ASC')->orderBy('turbines.turbine_code', 'ASC')->findAll()
        );
    }

    public function create()
    {
        if ($response = $this->requireAnyApiScope(['turbines:write', 'meters:write'])) {
            return $response;
        }

        $payload = $this->payload();
        $data = [
            'site_id' => (int) ($payload['site_id'] ?? 0),
            'turbine_code' => trim((string) ($payload['turbine_code'] ?? '')),
            'name' => trim((string) ($payload['name'] ?? '')) ?: null,
            'manufacturer' => trim((string) ($payload['manufacturer'] ?? '')) ?: null,
            'model' => trim((string) ($payload['model'] ?? '')) ?: null,
            'serial_number' => trim((string) ($payload['serial_number'] ?? '')) ?: null,
            'rated_power_kw' => $this->nullableDecimal($payload['rated_power_kw'] ?? null),
            'hub_height_m' => $this->nullableDecimal($payload['hub_height_m'] ?? null),
            'rotor_diameter_m' => $this->nullableDecimal($payload['rotor_diameter_m'] ?? null),
            'commissioned_at' => trim((string) ($payload['commissioned_at'] ?? '')) ?: null,
            'status' => trim((string) ($payload['status'] ?? 'active')) ?: 'active',
        ];

        $rules = [
            'site_id' => 'required|integer',
            'turbine_code' => 'required|max_length[80]',
            'name' => 'permit_empty|max_length[160]',
            'manufacturer' => 'permit_empty|max_length[120]',
            'model' => 'permit_empty|max_length[120]',
            'serial_number' => 'permit_empty|max_length[120]',
            'rated_power_kw' => 'permit_empty|decimal',
            'hub_height_m' => 'permit_empty|decimal',
            'rotor_diameter_m' => 'permit_empty|decimal',
            'commissioned_at' => 'permit_empty|valid_date[Y-m-d]',
            'status' => 'required|in_list[active,inactive,pending,maintenance]',
        ];

        if (! $this->validateData($data, $rules)) {
            return $this->failValidation($this->validator->getErrors());
        }

        $site = (new SiteModel())->find($data['site_id']);
        if (! $site || (int) $site['organization_id'] !== $this->apiOrganizationId()) {
            return $this->failForbidden('The selected site does not belong to this API key tenant.');
        }

        $model = new TurbineModel();
        $exists = $model
            ->where('site_id', $data['site_id'])
            ->where('turbine_code', $data['turbine_code'])
            ->first();

        if ($exists) {
            return $this->failValidation([
                'turbine_code' => 'A turbine with this code already exists for the selected site.',
            ]);
        }

        $id = $model->insert($data, true);

        return $this->respondOk($model->find($id), 201);
    }

    private function nullableDecimal($value): ?string
    {
        $value = trim((string) $value);

        return $value === '' ? null : $value;
    }
}
