<?php

namespace App\Livewire;

use App\Models\Association;
use App\Models\Org;
use App\Models\User;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Livewire\Component;
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
use Ysfkaya\FilamentPhoneInput\PhoneInputNumberType;

class RegisterAssociation extends Component implements HasSchemas
{
    use InteractsWithSchemas;

    public $orgId;

    public ?array $data = [];

    public function mount($orgId): void
    {
        $this->orgId = $orgId;
        $this->form->fill();
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('name')
                    ->label(__('association.name'))
                    ->placeholder(__('association.name_placeholder'))
                    ->maxLength(255)
                    ->required(),

                TextInput::make('license_number')
                    ->label(__('association.license_number'))
                    ->placeholder(__('association.license_number_placeholder'))
                    ->maxLength(255)
                    ->numeric()
                    ->rules(['regex:/^[1-9][0-9]*$/'])
                    ->validationMessages([
                        'regex' => __('association.license_number_no_leading_zero'),
                    ])
                    ->required(),

                DatePicker::make('license_expiration_date')
                    ->label(__('association.license_expiration_date'))
                    ->required()
                    ->after('today'),

                TextInput::make('representative_full_name')
                    ->label(__('association.representative'))
                    ->placeholder(__('association.representative_placeholder'))
                    ->required()
                    ->maxLength(255)
                    ->columnSpanFull(),

                TextInput::make('representative_position')
                    ->label(__('association.position'))
                    ->placeholder(__('association.position_placeholder'))
                    ->required()
                    ->maxLength(255)
                    ->columnSpanFull(),

                PhoneInput::make('phone')
                    ->label(__('association.phone_number'))
                    ->defaultCountry('SA')
                    ->onlyCountries(['sa'])
                    ->validateFor('SA')
                    ->displayNumberFormat(PhoneInputNumberType::NATIONAL)
                    ->inputNumberFormat(PhoneInputNumberType::E164)
                    ->separateDialCode(true)
                    ->formatAsYouType()
                    ->disallowDropdown()
                    ->extraAttributes([
                        'dir' => 'ltr',
                        'style' => 'direction: ltr; text-align: left;',
                    ]),

                TextInput::make('email')
                    ->label(__('association.email'))
                    ->placeholder(__('association.email_placeholder'))
                    ->email()
                    ->required()
                    ->maxLength(255)
                    ->live(onBlur: true)
                    ->extraAttributes([
                        'dir' => 'ltr',
                        'style' => 'direction: ltr; text-align: left;',
                    ]),
            ])
            ->statePath('data')
            ->columns(2);
    }

    public function submit(): void
    {
        $state = $this->form->getState();

        $email = $state['email'] ?? null;
        if (! $email) {
            session()->flash('error', __('association.email_required'));

            return;
        }

        $phone = $state['phone'] ?? null;
        if (! $phone) {
            session()->flash('error', __('association.phone_number_required'));

            return;
        }

        // find the user by email or phone
        $existingUser = User::where('email', 'ILIKE', trim(strtolower($email)))
            ->orWhere('phone', $phone)
            ->first();

        // if the user exists and the phone number or email does not match, show error
        if ($existingUser && ($existingUser->phone !== $phone || $existingUser->email !== $email)) {
            session()->flash('error', __('association.email_phone_mismatch'));

            return;
        }

        // if the user is already has this organization, show error
        if ($existingUser && $existingUser->orgs()->where('org_id', $this->orgId)->exists()) {
            session()->flash('error', __('association.user_already_in_org'));

            return;
        }

        // proceed to register the association
        $this->registerAssociation($state, $existingUser);

    }

    public function registerAssociation($data, $user): void
    {

        // check if license_number already exists
        if (
            Association::where('license_number', $data['license_number'])
                ->where('org_id', $this->orgId)
                ->exists()
        ) {
            session()->flash('error', __('association.license_number_already_registered'));

            return;
        }

        try {
            DB::transaction(function () use ($data, $user) {

                $admin = $user;
                if (! $admin) {
                    $admin = User::create([
                        'name' => $data['representative_full_name'],
                        'email' => $data['email'],
                        'phone' => $data['phone'],
                        'password' => Hash::make('Test@123'),   // Hash::make(Str::random(16)),
                    ]);
                }

                // assign user to org
                $admin->orgs()->attach($this->orgId);

                // $admin->assignRole('مدير جمعية');

                // Create association
                $association = Association::create([
                    'name' => $data['name'],

                    'license_number' => $data['license_number'],
                    'license_expiration_date' => $data['license_expiration_date'],

                    'user_id' => $admin->id,
                    'org_id' => $this->orgId,

                    'is_verified' => false,
                    'is_locked' => false,
                ]);

                $admin->setAssociationInOrg(Org::find($this->orgId), $association);
            });
        } catch (\Exception $e) {
            Log::error('Association promotion failed', [
                'error' => $e->getMessage(),
            ]);
            session()->flash('error', __('association.system_error'));

            return;
        }

        Log::info('Association registration completed');
        redirect()->route('filament.association.auth.login');
    }

    public function render()
    {
        return view('livewire.register-association');
    }
}
