function Write-ProjectFile {
    param(
        [Parameter(Mandatory = $true)][string]$Path,
        [Parameter(Mandatory = $true)][string]$Content
    )

    $directory = Split-Path -Parent $Path
    if ($directory) {
        New-Item -ItemType Directory -Force -Path $directory | Out-Null
    }

    Set-Content -LiteralPath $Path -Value $Content -NoNewline
}

Write-ProjectFile 'app/Services/Templates/TemplateVariableCatalog.php' @'
<?php

namespace App\Services\Templates;

use App\Enums\ResponseTemplateCategory;
use App\Enums\ResponseTemplateChannel;

class TemplateVariableCatalog
{
    public static function channels(): array
    {
        return array_map(
            fn (ResponseTemplateChannel $channel): array => [
                'value' => $channel->value,
                'label' => $channel->label(),
            ],
            ResponseTemplateChannel::cases(),
        );
    }

    public static function categories(): array
    {
        return array_map(
            fn (ResponseTemplateCategory $category): array => [
                'value' => $category->value,
                'label' => $category->label(),
            ],
            ResponseTemplateCategory::cases(),
        );
    }

    public static function definitions(): array
    {
        return [
            'name' => ['label' => 'Name', 'description' => 'Contact person name.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'email' => ['label' => 'Email', 'description' => 'Contact email address.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'company' => ['label' => 'Company', 'description' => 'Company name from the inquiry.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'phone' => ['label' => 'Phone', 'description' => 'Phone number from the inquiry.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'subject' => ['label' => 'Subject', 'description' => 'Inquiry subject line.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'message' => ['label' => 'Message', 'description' => 'Full inquiry message.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'message_preview' => ['label' => 'Message Preview', 'description' => 'Shortened version of the inquiry body.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'source_page' => ['label' => 'Source Page', 'description' => 'Landing page or URL where the message was submitted.', 'categories' => ['lead_received', 'follow_up', 'custom']],
            'created_at' => ['label' => 'Created At', 'description' => 'Timestamp of the source event.', 'categories' => ['lead_received', 'follow_up', 'article_published', 'system_alert', 'custom']],
            'admin_reference' => ['label' => 'Admin Reference', 'description' => 'Admin-side identifier or reference string.', 'categories' => ['lead_received', 'follow_up', 'article_published', 'system_alert', 'custom']],
            'article_title' => ['label' => 'Article Title', 'description' => 'Published article title.', 'categories' => ['article_published', 'custom']],
            'article_slug' => ['label' => 'Article Slug', 'description' => 'Published article slug.', 'categories' => ['article_published', 'custom']],
            'published_at' => ['label' => 'Published At', 'description' => 'Article publication timestamp.', 'categories' => ['article_published', 'custom']],
            'environment' => ['label' => 'Environment', 'description' => 'Deployment or build environment.', 'categories' => ['system_alert', 'custom']],
            'status' => ['label' => 'Status', 'description' => 'Operational status of the alert source.', 'categories' => ['system_alert', 'custom']],
            'error_message' => ['label' => 'Error Message', 'description' => 'Error details for failed operational events.', 'categories' => ['system_alert', 'custom']],
            'started_at' => ['label' => 'Started At', 'description' => 'Start time for an operational event.', 'categories' => ['system_alert', 'custom']],
            'finished_at' => ['label' => 'Finished At', 'description' => 'Finish time for an operational event.', 'categories' => ['system_alert', 'custom']],
            'alert_title' => ['label' => 'Alert Title', 'description' => 'Headline for a system alert.', 'categories' => ['system_alert', 'custom']],
            'alert_message' => ['label' => 'Alert Message', 'description' => 'Body text for a system alert.', 'categories' => ['system_alert', 'custom']],
            'occurred_at' => ['label' => 'Occurred At', 'description' => 'When the critical event happened.', 'categories' => ['system_alert', 'custom']],
            'context_json' => ['label' => 'Context JSON', 'description' => 'Serialized structured context for alerts.', 'categories' => ['system_alert', 'custom']],
        ];
    }

    public static function variableNames(): array
    {
        return array_keys(self::definitions());
    }

    public static function allowedForCategory(ResponseTemplateCategory|string|null $category): array
    {
        $categoryValue = $category instanceof ResponseTemplateCategory
            ? $category->value
            : ($category ?? ResponseTemplateCategory::CUSTOM->value);

        return collect(self::definitions())
            ->filter(fn (array $definition): bool => in_array($categoryValue, $definition['categories'], true) || in_array('custom', $definition['categories'], true))
            ->keys()
            ->values()
            ->all();
    }

    public static function sampleData(ResponseTemplateCategory|string|null $category): array
    {
        $categoryValue = $category instanceof ResponseTemplateCategory
            ? $category->value
            : ($category ?? ResponseTemplateCategory::CUSTOM->value);

        return match ($categoryValue) {
            ResponseTemplateCategory::LEAD_RECEIVED->value, ResponseTemplateCategory::FOLLOW_UP->value => [
                'name' => 'Alex Morgan',
                'email' => 'alex@example.com',
                'company' => 'Northwind Labs',
                'phone' => '+49 30 555 0101',
                'subject' => 'Website redesign inquiry',
                'message' => 'We would like to discuss a redesign and new content workflow.',
                'message_preview' => 'We would like to discuss a redesign and new content workflow.',
                'source_page' => 'https://itcarrot.com/contact',
                'created_at' => '2026-04-03 14:20:00',
                'admin_reference' => 'Message #42',
            ],
            ResponseTemplateCategory::ARTICLE_PUBLISHED->value => [
                'article_title' => 'How Itcarrot structures modern content operations',
                'article_slug' => 'how-itcarrot-structures-modern-content-operations',
                'published_at' => '2026-04-03 15:30:00',
                'created_at' => '2026-04-03 15:30:00',
                'admin_reference' => 'Article #12',
            ],
            ResponseTemplateCategory::SYSTEM_ALERT->value => [
                'environment' => 'production',
                'status' => 'failed',
                'error_message' => 'Astro build failed during static generation.',
                'started_at' => '2026-04-03 16:00:00',
                'finished_at' => '2026-04-03 16:02:12',
                'alert_title' => 'Critical service degradation',
                'alert_message' => 'The deployment pipeline reported a blocking failure.',
                'occurred_at' => '2026-04-03 16:02:12',
                'context_json' => '{"service":"astro-build","severity":"critical"}',
                'created_at' => '2026-04-03 16:02:12',
                'admin_reference' => 'Build #8',
            ],
            default => [
                'name' => 'Alex Morgan',
                'email' => 'alex@example.com',
                'company' => 'Northwind Labs',
                'phone' => '+49 30 555 0101',
                'subject' => 'General inquiry',
                'message' => 'This is sample content used for template previews.',
                'message_preview' => 'This is sample content used for template previews.',
                'source_page' => 'https://itcarrot.com/contact',
                'created_at' => '2026-04-03 14:20:00',
                'admin_reference' => 'Reference #1',
                'article_title' => 'Sample Article',
                'article_slug' => 'sample-article',
                'published_at' => '2026-04-03 15:30:00',
                'environment' => 'production',
                'status' => 'pending',
                'error_message' => 'Example failure message',
                'started_at' => '2026-04-03 16:00:00',
                'finished_at' => '2026-04-03 16:02:12',
                'alert_title' => 'Example alert',
                'alert_message' => 'Example alert body',
                'occurred_at' => '2026-04-03 16:02:12',
                'context_json' => '{"example":true}',
            ],
        };
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Messages/StoreWebsiteMessageRequest.php' @'
<?php

namespace App\Http\Requests\Messages;

use Illuminate\Foundation\Http\FormRequest;

class StoreWebsiteMessageRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255'],
            'company' => ['nullable', 'string', 'max:255'],
            'phone' => ['nullable', 'string', 'max:50'],
            'subject' => ['nullable', 'string', 'max:255'],
            'message' => ['required', 'string', 'max:10000'],
            'source_page' => ['nullable', 'string', 'max:2048'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Templates/IndexResponseTemplateRequest.php' @'
<?php

namespace App\Http\Requests\Templates;

use App\Services\Templates\TemplateVariableCatalog;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class IndexResponseTemplateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'search' => ['nullable', 'string', 'max:255'],
            'channel' => ['nullable', Rule::in(array_column(TemplateVariableCatalog::channels(), 'value'))],
            'category' => ['nullable', Rule::in(array_column(TemplateVariableCatalog::categories(), 'value'))],
            'is_active' => ['nullable', 'boolean'],
            'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Templates/StoreResponseTemplateRequest.php' @'
<?php

namespace App\Http\Requests\Templates;

use App\Enums\ResponseTemplateChannel;
use App\Services\Templates\TemplateVariableCatalog;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StoreResponseTemplateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'slug' => ['nullable', 'string', 'max:255', 'regex:/^[a-z0-9-]+$/', Rule::unique('response_templates', 'slug')],
            'channel' => ['required', Rule::in(array_column(TemplateVariableCatalog::channels(), 'value'))],
            'category' => ['required', Rule::in(array_column(TemplateVariableCatalog::categories(), 'value'))],
            'subject' => [
                'nullable',
                'string',
                'max:255',
                Rule::requiredIf(fn (): bool => $this->input('channel') === ResponseTemplateChannel::EMAIL->value),
            ],
            'body' => ['required', 'string'],
            'variables_json' => ['nullable', 'array'],
            'variables_json.*' => ['string', Rule::in(TemplateVariableCatalog::variableNames())],
            'is_active' => ['sometimes', 'boolean'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Templates/UpdateResponseTemplateRequest.php' @'
<?php

namespace App\Http\Requests\Templates;

use App\Enums\ResponseTemplateChannel;
use App\Services\Templates\TemplateVariableCatalog;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UpdateResponseTemplateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        $templateId = $this->route('template')?->getKey();
        $channel = $this->input('channel') ?? $this->route('template')?->channel?->value;

        return [
            'name' => ['sometimes', 'string', 'max:255'],
            'slug' => ['nullable', 'string', 'max:255', 'regex:/^[a-z0-9-]+$/', Rule::unique('response_templates', 'slug')->ignore($templateId)],
            'channel' => ['sometimes', Rule::in(array_column(TemplateVariableCatalog::channels(), 'value'))],
            'category' => ['sometimes', Rule::in(array_column(TemplateVariableCatalog::categories(), 'value'))],
            'subject' => [
                'nullable',
                'string',
                'max:255',
                Rule::requiredIf(fn (): bool => $channel === ResponseTemplateChannel::EMAIL->value),
            ],
            'body' => ['sometimes', 'string'],
            'variables_json' => ['nullable', 'array'],
            'variables_json.*' => ['string', Rule::in(TemplateVariableCatalog::variableNames())],
            'is_active' => ['sometimes', 'boolean'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Templates/PreviewResponseTemplateRequest.php' @'
<?php

namespace App\Http\Requests\Templates;

use App\Enums\ResponseTemplateChannel;
use App\Services\Templates\TemplateVariableCatalog;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class PreviewResponseTemplateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'name' => ['nullable', 'string', 'max:255'],
            'slug' => ['nullable', 'string', 'max:255', 'regex:/^[a-z0-9-]+$/'],
            'channel' => ['required', Rule::in(array_column(TemplateVariableCatalog::channels(), 'value'))],
            'category' => ['required', Rule::in(array_column(TemplateVariableCatalog::categories(), 'value'))],
            'subject' => [
                'nullable',
                'string',
                'max:255',
                Rule::requiredIf(fn (): bool => $this->input('channel') === ResponseTemplateChannel::EMAIL->value),
            ],
            'body' => ['required', 'string'],
            'variables_json' => ['nullable', 'array'],
            'variables_json.*' => ['string', Rule::in(TemplateVariableCatalog::variableNames())],
            'sample_data' => ['nullable', 'array'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Logs/IndexEmailLogRequest.php' @'
<?php

namespace App\Http\Requests\Logs;

use App\Enums\EmailLogStatus;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class IndexEmailLogRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'search' => ['nullable', 'string', 'max:255'],
            'status' => ['nullable', Rule::in(array_map(fn (EmailLogStatus $status): string => $status->value, EmailLogStatus::cases()))],
            'template_id' => ['nullable', 'integer', 'exists:response_templates,id'],
            'date_from' => ['nullable', 'date'],
            'date_to' => ['nullable', 'date'],
            'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Logs/IndexTelegramLogRequest.php' @'
<?php

namespace App\Http\Requests\Logs;

use App\Enums\TelegramEventType;
use App\Enums\TelegramLogStatus;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class IndexTelegramLogRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'status' => ['nullable', Rule::in(array_map(fn (TelegramLogStatus $status): string => $status->value, TelegramLogStatus::cases()))],
            'event_type' => ['nullable', Rule::in(array_map(fn (TelegramEventType $eventType): string => $eventType->value, TelegramEventType::cases()))],
            'date_from' => ['nullable', 'date'],
            'date_to' => ['nullable', 'date'],
            'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Requests/Integrations/TestTelegramNotificationRequest.php' @'
<?php

namespace App\Http\Requests\Integrations;

use Illuminate\Foundation\Http\FormRequest;

class TestTelegramNotificationRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'message' => ['nullable', 'string', 'max:1000'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/WebsiteMessageResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class WebsiteMessageResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'company' => $this->company,
            'phone' => $this->phone,
            'subject' => $this->subject,
            'message' => $this->message,
            'source_page' => $this->source_page,
            'status' => $this->status,
            'internal_notes' => $this->internal_notes,
            'handled_at' => $this->handled_at?->toIso8601String(),
            'metadata' => $this->metadata ?? [],
            'handler' => UserResource::make($this->whenLoaded('handler')),
            'email_logs_count' => $this->whenCounted('emailLogs'),
            'telegram_logs_count' => $this->whenCounted('telegramLogs'),
            'created_at' => $this->created_at?->toIso8601String(),
            'updated_at' => $this->updated_at?->toIso8601String(),
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/ResponseTemplateResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class ResponseTemplateResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'slug' => $this->slug,
            'channel' => $this->channel->value,
            'channel_label' => $this->channel->label(),
            'category' => $this->category->value,
            'category_label' => $this->category->label(),
            'subject' => $this->subject,
            'body' => $this->body,
            'variables_json' => $this->variables_json ?? [],
            'is_active' => $this->is_active,
            'creator' => UserResource::make($this->whenLoaded('creator')),
            'updater' => UserResource::make($this->whenLoaded('updater')),
            'created_at' => $this->created_at?->toIso8601String(),
            'updated_at' => $this->updated_at?->toIso8601String(),
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/EmailLogResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class EmailLogResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'to_email' => $this->to_email,
            'subject' => $this->subject,
            'status' => $this->status->value,
            'provider' => $this->provider,
            'error_message' => $this->error_message,
            'rendered_body' => $this->rendered_body,
            'meta_json' => $this->meta_json ?? [],
            'sent_at' => $this->sent_at?->toIso8601String(),
            'template' => $this->whenLoaded('template', fn (): array => [
                'id' => $this->template?->id,
                'name' => $this->template?->name,
                'slug' => $this->template?->slug,
            ]),
            'website_message' => $this->whenLoaded('websiteMessage', fn (): array => [
                'id' => $this->websiteMessage?->id,
                'name' => $this->websiteMessage?->name,
                'email' => $this->websiteMessage?->email,
                'subject' => $this->websiteMessage?->subject,
            ]),
            'created_at' => $this->created_at?->toIso8601String(),
            'updated_at' => $this->updated_at?->toIso8601String(),
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/TelegramLogResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class TelegramLogResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'chat_id' => $this->chat_id,
            'event_type' => $this->event_type->value,
            'event_type_label' => $this->event_type->label(),
            'status' => $this->status->value,
            'rendered_message' => $this->rendered_message,
            'telegram_message_id' => $this->telegram_message_id,
            'error_message' => $this->error_message,
            'meta_json' => $this->meta_json ?? [],
            'sent_at' => $this->sent_at?->toIso8601String(),
            'template' => $this->whenLoaded('template', fn (): array => [
                'id' => $this->template?->id,
                'name' => $this->template?->name,
                'slug' => $this->template?->slug,
            ]),
            'website_message' => $this->whenLoaded('websiteMessage', fn (): array => [
                'id' => $this->websiteMessage?->id,
                'name' => $this->websiteMessage?->name,
                'email' => $this->websiteMessage?->email,
                'subject' => $this->websiteMessage?->subject,
            ]),
            'created_at' => $this->created_at?->toIso8601String(),
            'updated_at' => $this->updated_at?->toIso8601String(),
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/TemplatePreviewResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class TemplatePreviewResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'channel' => $this->resource['channel'],
            'category' => $this->resource['category'],
            'subject' => $this->resource['subject'],
            'body' => $this->resource['body'],
            'used_placeholders' => $this->resource['used_placeholders'],
            'available_placeholders' => $this->resource['available_placeholders'],
            'sample_data' => $this->resource['sample_data'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/TemplateMetaResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class TemplateMetaResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'channels' => $this->resource['channels'],
            'categories' => $this->resource['categories'],
            'placeholder_catalog' => $this->resource['placeholder_catalog'],
            'preview_samples' => $this->resource['preview_samples'],
        ];
    }
}
'@

Write-ProjectFile 'app/Http/Resources/IntegrationStatusResource.php' @'
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class IntegrationStatusResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'email' => $this->resource['email'],
            'telegram' => $this->resource['telegram'],
        ];
    }
}
'@
