<?php

namespace App\Http\Resources;

use App\Enums\CSVDelimiter;
use App\Enums\ExportColumnJsonType;
use App\ExportMaps\Contracts\ExportMapType;
use App\Exports\JsonMapExport;
use App\IntegrationRepository;
use App\Models\ExportMapTemplate;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\SalesChannelHistory;

class ExportMapResource extends JsonResource
{
    public static $wrap = '';

    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    #[\Override]
    public function toArray(Request $request): array
    {
        $this->resource->row_data = collect($this->resource->data['row_data'] ?? [])->keys();
        $resource = $this->resource->toArray();

        $resource['api_url'] = $this->resource->getApiUrl();
        $resource['api_url_enabled'] = $this->resource->api_url_enabled;

        $resource['data_options'] = [
            'types' => collect(config('export_maps.types', []))
                ->map(fn ($type, $key) => [
                    'id' => $key,
                    'name' => App::make($type)->name(),
                ])->values(),
            'schedules' => collect(config('export_maps.schedule_types', []))
                ->map(fn ($type, $key) => [
                    'id' => $key,
                    'name' => __('export_maps.schedule_types.' . $key),
                ])->values(),
            'export_formats' => collect(config('export_maps.export_formats', []))
                ->map(fn ($type) => [
                    'id' => $type,
                    'name' => $type,
                ])->values(),
            'operators' => collect(config('export_maps.operators', []))
                ->map(fn ($type) => [
                    'id' => $type,
                    'name' => __('export_maps.operators.' . $type),
                ])->values(),
            'day_of_week' => collect(range(1, 7))
                ->map(fn ($day) => [
                    'id' => $day,
                    'name' => __('export_maps.day_of_week.' . $day),
                ])->values(),
            'day_of_month' => collect(range(1, 28))
                ->map(fn ($day) => [
                    'id' => $day,
                    'name' => $day,
                ])->values(),
            'export_drivers' => [
                [
                    'id' => 'sftp',
                    'name' => 'SFTP'
                ],
                [
                    'id' => 'ftp',
                    'name' => 'FTP'
                ],
            ],
            'mapping_operators' => trans('export_map.operators'),
            'available_fields' => collect($this->getFieldsForType())
                ->map(fn ($value, $key) => [
                    'id' => $key,
                    'name' => "$value ($key) ",
                ])
                ->sortBy('name')
                ->values(),
            'condition_fields' => collect($this->getQueryableFieldsForType())
                ->map(fn ($value, $key) => [
                    'id' => $key,
                    'name' => "$value ($key) ",
                ])
                ->sortBy('name')
                ->values(),
            'templates' => ExportMapTemplate::query()
                ->published()
                ->where('type', $this->resource->type)
                ->where(function ($query) {
                    $query
                        ->whereIn('sales_channel', $this->getAllowedSalesChannels())
                        ->orWhereNull('sales_channel')
                        ->orWhere('sales_channel', '');
                })
                ->get(),
            'csv_delimiters' => collect(CSVDelimiter::cases())
                ->map(fn ($case) => [
                    'id' => $case->value,
                    'name' => $case->name,
                ])
                ->values(),
            'column_json_types' => collect(ExportColumnJsonType::cases())
                ->map(fn ($case) => [
                    'id' => $case->value,
                    'name' => $case->value,
                ])
                ->values(),
            'json_envelope_tokens' => JsonMapExport::envelopeTokenCatalogue(),
        ];

        $resource['conditions'] = $this->resource->conditions ?? [];
        $resource['logs'] = $this->recentLogs();
        return $resource;
    }

    /**
     * Recent export-run outcomes from the sales channel history (keyed by the
     * export map's stable id-based channel key), newest first, for the edit page.
     */
    private function recentLogs(): array
    {
        return SalesChannelHistory::query()
            ->where('channel', $this->resource->salesChannelKey())
            ->latest()
            ->limit(10)
            ->get()
            ->map(function (SalesChannelHistory $history) {
                $data = $history->data ?? [];

                return [
                    'id' => $history->id,
                    'status' => $history->was_successful ? 'success' : 'failed',
                    'message' => $history->details,
                    'records' => $data['records'] ?? null,
                    'filename' => $data['filename'] ?? null,
                    'file_verified' => $data['file_verified'] ?? null,
                    'created_at' => $history->created_at?->format('d/m/Y H:i'),
                ];
            })
            ->all();
    }

    private function getFieldsForType(): array
    {
        $typeInstance = $this->resolveTypeInstance();
        return $typeInstance ? $typeInstance->columns(true) : [];
    }

    private function getQueryableFieldsForType(): array
    {
        $typeInstance = $this->resolveTypeInstance();
        return $typeInstance ? $typeInstance->queryableColumns(true) : [];
    }

    private function resolveTypeInstance(): ?ExportMapType
    {
        $typeClass = config('export_maps.types.' . $this->resource->type);
        return $typeClass ? App::make($typeClass) : null;
    }

    private function getAllowedSalesChannels(): array
    {
        return App::make(IntegrationRepository::class)
            ->getEnabledForType('sales-channels')
            ->keys()
            ->all();
    }
}
