<?php

namespace App\Livewire\Participants;

use App\Domain\Identity\Models\Person;
use App\Domain\Participant\Models\Participant;
use App\Domain\Shared\Traits\UsesBranchScope;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use App\Domain\Shared\Traits\ChecksTemporaryUploads;
use Livewire\WithFileUploads;

#[Layout('layouts.app')]
#[Title('استيراد مشتركين')]
class ParticipantImport extends Component
{
    use WithFileUploads, UsesBranchScope;
    use ChecksTemporaryUploads;

    public $file;
    public array $preview = [];
    public array $importErrors = [];
    public int $imported = 0;
    public int $skipped = 0;
    public bool $processing = false;
    public bool $done = false;

    public function mount(): void
    {
        $this->authorize('participants.create');
    }

    public function rules(): array
    {
        return [
            'file' => 'required|file|mimes:csv,txt|max:5120',
        ];
    }

    public function updatedFile(): void
    {
        if (! $this->temporaryUploadIsUsable('file', $this->file)) {
            return;
        }

        $this->validate();
        $this->preview = [];
        $this->importErrors = [];

        $path = $this->file->getRealPath();
        $handle = fopen($path, 'r');

        $header = fgetcsv($handle);
        if (!$header) {
            $this->importErrors[] = 'الملف فارغ أو غير صالح';
            fclose($handle);
            return;
        }

        $header = array_map('trim', $header);
        $required = ['name_ar', 'phone'];
        $missing = array_diff($required, $header);
        if (!empty($missing)) {
            $this->importErrors[] = 'أعمدة مفقودة: ' . implode(', ', $missing);
            fclose($handle);
            return;
        }

        $rows = 0;
        while (($row = fgetcsv($handle)) !== false && $rows < 5) {
            $data = array_combine($header, $row);
            $this->preview[] = $data;
            $rows++;
        }

        fclose($handle);
    }

    public function import(): void
    {
        if (! $this->temporaryUploadIsUsable('file', $this->file)) {
            return;
        }

        $this->validate();
        $this->processing = true;
        $this->imported = 0;
        $this->skipped = 0;
        $this->importErrors = [];

        $branchId = $this->getActiveBranchIdOrFail();
        $path = $this->file->getRealPath();
        $handle = fopen($path, 'r');
        $header = array_map('trim', fgetcsv($handle));

        $lineNum = 1;
        DB::beginTransaction();

        try {
            while (($row = fgetcsv($handle)) !== false) {
                $lineNum++;
                if (count($row) !== count($header)) {
                    $this->importErrors[] = "سطر {$lineNum}: عدد الأعمدة غير متطابق";
                    $this->skipped++;
                    continue;
                }

                $data = array_combine($header, array_map('trim', $row));

                $validator = Validator::make($data, [
                    'name_ar' => 'required|string|max:255',
                    'phone' => 'required|string|max:20',
                ]);

                if ($validator->fails()) {
                    $this->importErrors[] = "سطر {$lineNum}: " . implode(', ', $validator->errors()->all());
                    $this->skipped++;
                    continue;
                }

                $person = Person::firstOrCreate(
                    ['phone' => $data['phone']],
                    [
                        'name_ar' => $data['name_ar'],
                        'name' => $data['name'] ?? null,
                        'email' => $data['email'] ?? null,
                        'gender' => $data['gender'] ?? null,
                        'date_of_birth' => $data['date_of_birth'] ?? null,
                        'nationality' => $data['nationality'] ?? 'EG',
                    ]
                );

                $existingParticipant = Participant::where('person_id', $person->id)
                    ->where('branch_id', $branchId)
                    ->first();

                if ($existingParticipant) {
                    $this->skipped++;
                    continue;
                }

                Participant::create([
                    'person_id' => $person->id,
                    'branch_id' => $branchId,
                    'academy_id' => app('current_academy')->id,
                    'status' => 'registered',
                    'membership_type' => $data['membership_type'] ?? 'non_member',
                    'membership_id' => $data['membership_id'] ?? null,
                    'created_by' => auth()->id(),
                ]);

                $this->imported++;
            }

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();
            $this->importErrors[] = 'خطأ: ' . $e->getMessage();
        }

        fclose($handle);
        $this->processing = false;
        $this->done = true;
    }

    /**
     * What each CSV column is called in this branch's own words.
     *
     * The column names themselves are the file format and never change —
     * a spreadsheet exported last year still imports. Only the explanation
     * beside them follows the branch: membership_type reads "نوع الإقامة" in
     * a compound and "نوع العضوية" in a club.
     *
     * @return array<string, string>
     */
    private function columnLabels(): array
    {
        return [
            'name_ar' => __('الاسم بالعربية'),
            'name' => __('الاسم بالإنجليزية'),
            'phone' => __('الهاتف'),
            'email' => __('البريد'),
            'gender' => __('الجنس'),
            'date_of_birth' => __('تاريخ الميلاد'),
            'nationality' => __('الجنسية'),
            'membership_type' => term('membership_type'),
            'membership_id' => term('membership_id'),
        ];
    }

    public function render()
    {
        return view('livewire.participants.participant-import', [
            'columnLabels' => $this->columnLabels(),
        ]);
    }
}
