<?php

namespace App\Livewire\Project\New;

use App\Models\EnvironmentVariable;
use App\Models\Project;
use App\Models\Service;
use Livewire\Component;
use Symfony\Component\Yaml\Yaml;

class DockerCompose extends Component
{
    public string $dockerComposeRaw = '';

    public string $envFile = '';

    public array $parameters;

    public array $query;

    public function mount()
    {
        $this->parameters = get_route_parameters();
        $this->query = request()->query();
        if (isDev()) {
            $this->dockerComposeRaw = file_get_contents(base_path('templates/test-database-detection.yaml'));
        }
    }

    public function submit()
    {
        try {
            $this->validate([
                'dockerComposeRaw' => 'required',
            ]);
            $this->dockerComposeRaw = Yaml::dump(Yaml::parse($this->dockerComposeRaw), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);

            // Validate for command injection BEFORE saving to database
            validateDockerComposeForInjection($this->dockerComposeRaw);

            $project = Project::ownedByCurrentTeam()->where('uuid', $this->parameters['project_uuid'])->firstOrFail();
            $environment = $project->environments()->where('uuid', $this->parameters['environment_uuid'])->firstOrFail();

            $destination_uuid = $this->query['destination'] ?? null;
            $destination = find_destination_for_current_team($destination_uuid);
            if (! $destination) {
                throw new \Exception('Destination not found.');
            }
            $destination_class = $destination->getMorphClass();

            $service = Service::create([
                'docker_compose_raw' => $this->dockerComposeRaw,
                'environment_id' => $environment->id,
                'server_id' => $destination->server_id,
                'destination_id' => $destination->id,
                'destination_type' => $destination_class,
            ]);

            $variables = parseEnvFormatToArray($this->envFile);
            foreach ($variables as $key => $data) {
                // Extract value and comment from parsed data
                // Handle both array format ['value' => ..., 'comment' => ...] and plain string values
                $value = is_array($data) ? ($data['value'] ?? '') : $data;
                $comment = is_array($data) ? ($data['comment'] ?? null) : null;

                EnvironmentVariable::create([
                    'key' => $key,
                    'value' => $value,
                    'comment' => $comment,
                    'is_preview' => false,
                    'resourceable_id' => $service->id,
                    'resourceable_type' => $service->getMorphClass(),
                ]);
            }
            $service->parse(isNew: true);

            // Apply service-specific application prerequisites
            applyServiceApplicationPrerequisites($service);

            return redirect()->route('project.service.configuration', [
                'service_uuid' => $service->uuid,
                'environment_uuid' => $environment->uuid,
                'project_uuid' => $project->uuid,
            ]);
        } catch (\Throwable $e) {
            return handleError($e, $this);
        }
    }
}
