<?php
namespace App\Exports;

use App\Models\FormResponse;
use App\Models\Form;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

class FormResponsesExport implements FromCollection, WithHeadings, WithMapping
{
    protected $formId;
    protected $allUniqueFields;
    protected $formResponses;
    protected $initialized = false;

    public function __construct($formId) {
        $this->formId = $formId;
        $this->allUniqueFields = collect();
    }

    private function initializeData()
    {
        if ($this->initialized) {
            return;
        }

        // Get all responses for this form
        $this->formResponses = FormResponse::where('form_id', $this->formId)
            ->with('form')
            ->orderBy('created_at', 'desc')
            ->get();

        // Collect all unique field names from ALL responses to handle structure changes
        foreach ($this->formResponses as $formResponse) {
            $responses = is_array($formResponse->responses)
                ? $formResponse->responses
                : json_decode($formResponse->responses, true);
            if (is_array($responses)) {
                $fieldKeys = array_keys($responses);
                foreach ($fieldKeys as $fieldKey) {
                    if (!$this->allUniqueFields->contains($fieldKey)) {
                        $this->allUniqueFields->push($fieldKey);
                    }
                }
            }
        }

        // Sort field keys to maintain consistent column order
        $this->allUniqueFields = $this->allUniqueFields->sort()->values();

        $this->initialized = true;
    }

    public function collection()
    {
        $this->initializeData();
        return $this->formResponses;
    }

    public function headings(): array
    {
        $this->initializeData();

        $headers = [
            'Response ID',
            'Form Title',
            'Submitted At',
            'Status',
            'Cancelled At',
        ];

        // Add all unique field names as column headers
        foreach ($this->allUniqueFields as $fieldKey) {
            // Try to get human-readable label from current form structure
            $fieldLabel = $this->getFieldLabel($fieldKey);
            $headers[] = $fieldLabel;
        }

        return $headers;
    }

    /**
     * Get human-readable label for field, fallback to field key if not found
     */
    private function getFieldLabel($fieldKey)
    {
        // Extract field ID from field key (e.g., "field_123" -> "123")
        if (preg_match('/field_(\d+)/', $fieldKey, $matches)) {
            $fieldId = $matches[1];

            // Try to get current form structure to find field label
            $form = Form::with(['formSections.formFields'])->find($this->formId);
            if ($form) {
                foreach ($form->formSections as $section) {
                    foreach ($section->formFields as $field) {
                        if ($field->form_field_id == $fieldId) {
                            return $field->title . " (ID: {$fieldId})";
                        }
                    }
                }
            }
        }

        // Fallback to field key if no label found
        return $fieldKey;
    }

    public function map($response): array
    {
        $results = [
            $response->id,
            $response->form->title ?? 'Form Deleted',
            $response->created_at->toDateTimeString(),
            $response->isCancelled() ? 'Cancelled' : 'Confirmed',
            $response->cancelled_at ? $response->cancelled_at->toDateTimeString() : '',
        ];

        // Add values for all unique fields, ensuring consistent column count
        $responses = is_array($response->responses)
            ? $response->responses
            : (json_decode($response->responses, true) ?? []);

        foreach ($this->allUniqueFields as $fieldKey) {
            $value = $responses[$fieldKey] ?? '';

            // Handle different value types
            if (is_array($value)) {
                // For checkbox fields, join array values
                $results[] = implode(', ', $value);
            } else {
                $results[] = $value;
            }
        }

        return $results;
    }
}
