<?php

namespace App\Services\Forms;

use App\Models\Form;
use App\Models\FormSubmission;
use Illuminate\Database\Eloquent\Builder;
use Symfony\Component\HttpFoundation\StreamedResponse;

class FormSubmissionExportService
{
    public function streamCsv(?int $companyId, ?int $formId = null, ?int $days = null): StreamedResponse
    {
        $query = $this->baseQuery($companyId, $formId, $days);
        $submissions = $query->get();
        $form = $formId ? Form::find($formId) : null;
        $fieldLabels = $this->fieldLabels($form, $submissions);

        $filename = 'form-submissions-' . ($form?->name ? str($form->name)->slug() : 'all') . '-' . now()->format('Ymd') . '.csv';

        return response()->streamDownload(function () use ($submissions, $fieldLabels) {
            $handle = fopen('php://output', 'w');
            $header = array_merge(['Submitted At', 'Employee', 'Form', 'Status'], $fieldLabels);
            fputcsv($handle, $header);

            foreach ($submissions as $submission) {
                $row = [
                    $submission->created_at?->toDateTimeString(),
                    $submission->user?->name,
                    $submission->form?->name,
                    $submission->status,
                ];
                $valuesByLabel = [];
                foreach ($submission->responses ?? [] as $response) {
                    $label = (string) ($response['label'] ?? '');
                    $value = $response['value'] ?? '';
                    if (($response['type'] ?? '') === 'checkbox') {
                        $value = ! empty($value) ? 'Yes' : 'No';
                    }
                    $valuesByLabel[$label] = is_scalar($value) ? (string) $value : json_encode($value);
                }
                foreach ($fieldLabels as $label) {
                    $row[] = $valuesByLabel[$label] ?? '';
                }
                fputcsv($handle, $row);
            }

            fclose($handle);
        }, $filename, ['Content-Type' => 'text/csv']);
    }

    /**
     * @return Builder<FormSubmission>
     */
    protected function baseQuery(?int $companyId, ?int $formId, ?int $days): Builder
    {
        $query = FormSubmission::with(['form', 'user'])->orderByDesc('created_at');

        if ($companyId) {
            $query->where('company_id', $companyId);
        }

        if ($formId) {
            $query->where('form_id', $formId);
        }

        if ($days) {
            $query->where('created_at', '>=', now()->subDays(max(1, min(365, $days))));
        }

        return $query;
    }

    /**
     * @param  \Illuminate\Support\Collection<int, FormSubmission>  $submissions
     * @return list<string>
     */
    protected function fieldLabels(?Form $form, $submissions): array
    {
        if ($form && ! empty($form->fields)) {
            return array_values(array_map(fn ($f) => (string) ($f['label'] ?? 'Field'), $form->fields));
        }

        $labels = [];
        foreach ($submissions as $submission) {
            foreach ($submission->responses ?? [] as $response) {
                $label = (string) ($response['label'] ?? '');
                if ($label !== '' && ! in_array($label, $labels, true)) {
                    $labels[] = $label;
                }
            }
        }

        return $labels;
    }
}
