<?php

namespace App\Nova\Resources\Order\Card;

use App\Models\Branch\Branch;
use App\Models\Order\Card\CardOrder as CardOrderModel;
use App\Nova\Filters\RegionFilter;
use App\Nova\Filters\StatusFilter;
use App\Nova\Forms\NovaForm;
use App\Nova\Resource;
use App\Nova\Resources\Order\Card\Concerns\CardOrderFieldsForDetail;
use App\Nova\Resources\Order\Card\Concerns\CardOrderFieldsForIndex;
use App\Repos\Order\Card\CardOrderRepo;
use App\Repos\Order\Card\CardStateRepo;
use App\Repos\Order\Card\CardTypeRepo;
use App\Repos\Order\OrderRepo;
use App\Repos\Payment\OnlinePaymentRepo;
use App\Repos\System\Location\CountryRepo;
use App\Repos\System\Nova\NovaRepo;
use App\Repos\System\Settings\Legal\PassportRepo;
use App\Repos\System\Settings\Location\RegionRepo;
use App\Rules\DowranAgaAllowed;
use App\Rules\OnlyLetters;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Image;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Panel;
use Laravel\Nova\URL;
use Nurmuhammet\NovaCustomHtml\NovaCustomHtml;
use Nurmuhammet\NovaInputmask\NovaInputmask;

class CardOrder extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var class-string<CardOrderModel>
     */
    public static $model = CardOrderModel::class;

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'unique_id';

    /**
     * The relationships that should be eager loaded on index queries.
     *
     * @var array
     */
    public static $with = ['branch', 'cardState', 'cardType'];

    /**
     * The columns that should be searched.
     *
     * @var array
     */
    public static $search = [
        'unique_id', 'customer_name', 'customer_surname', 'phone',
    ];

    /**
     * Indicates whether the resource should automatically poll for new resources.
     *
     * @var bool
     */
    public static $polling = true;

    /**
     * The interval at which Nova should poll for new resources.
     *
     * @var int
     */
    public static $pollingInterval = 120;

    /**
     * Indicates whether to show the polling toggle button inside Nova.
     *
     * @var bool
     */
    public static $showPollingToggle = true;

    /**
     * Get the displayable label of the resource.
     */
    public static function label(): string
    {
        return __('Card orders');
    }

    /**
     * Get the displayable singular label of the resource.
     */
    public static function singularLabel(): string
    {
        return __('Card order');
    }

    /**
     * Build an "index" query for the given resource.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function indexQuery(NovaRequest $request, $query)
    {
        $user = $request->user();

        if ($user->isAdmin()) {
            return $query;
        }

        if ($user->isOperator()) {
            return $query->whereIn('branch_id', $user->branches()->pluck('branches.id'));
        }

        return $query->where('user_id', $request->user()->id);
    }

    /**
     * After resource created
     *
     * @param  Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  Illuminate\Database\Eloquent\Model  $model
     */
    public static function afterCreate(NovaRequest $request, Model $model): void
    {
        CardOrderRepo::created()($model);
    }

    /**
     * Return the location to redirect the user after update.
     *
     * @param  \Laravel\Nova\Resource  $resource
     */
    // public static function redirectAfterUpdate(NovaRequest $request, $resource): URL|string
    // {
    //     $payment = (new OnlinePaymentRepo())->payCardOrder($resource);

    //     return $payment['status'] === 'success'
    //         ? URL::remote($payment['url'])
    //         : sprintf('resources/%s/%s', static::uriKey(), $resource->getKey());
    // }

    /**
     * Get the fields for index.
     */
    public function fieldsForIndex(NovaRequest $request): array
    {
        return CardOrderFieldsForIndex::make($this);
    }

    /**
     * Get the fields for detail
     */
    public function fieldsForDetail(): array
    {
        return CardOrderFieldsForDetail::make($this);
    }

    /**
     * Get the fields displayed by the resource.
     */
    public function fields(NovaRequest $request): array
    {
        return [
            ID::make(),

            Hidden::make('user_id')
                ->default(auth()->id())
                ->hideWhenUpdating(),

            Select::make(__('Status'), 'status')
                ->displayUsingLabels()
                ->searchable()
                ->options(OrderRepo::statusValues())
                ->default(OrderRepo::defaultStatus())
                ->fullWidth()
                ->rules('required')
                ->canSeeWhen('systemUser', $this),

            Text::make(__('Note'), 'notes')
                ->fullWidth()
                ->canSeeWhen('systemUser', $this),

            new Panel(__('Card'), [
                Select::make(__('Reason for issuing the card'), 'card_state_id')
                    ->displayUsingLabels()
                    ->fullWidth()
                    ->searchable()
                    ->options(CardStateRepo::values())
                    ->size('w-1/2')
                    ->rules('required'),

                Select::make(__('Card type'), 'card_type_id')
                    ->displayUsingLabels()
                    ->fullWidth()
                    ->searchable()
                    ->options(CardTypeRepo::values())
                    ->size('w-1/2')
                    ->rules('required'),
            ]),

            new Panel(__('Location'), [
                Select::make(__('Region'), 'region')
                    ->displayUsingLabels()
                    ->searchable()
                    ->options(RegionRepo::values())
                    ->default(RegionRepo::default())
                    ->size('w-1/2')
                    ->rules('required'),

                Select::make(__('Branch'), 'branch_id')
                    ->displayUsingLabels()
                    ->searchable()
                    ->dependsOn('region', NovaRepo::dependsOnRegion('region', Branch::class))
                    ->size('w-1/2')
                    ->rules('required'),
            ]),

            new Panel(__('Personal data'), [
                Text::make(__('Name'), 'customer_name')
                    ->size('w-1/3')
                    ->rules('required', 'string', new OnlyLetters(), 'max:255'),

                Text::make(__('Surname'), 'customer_surname')
                    ->size('w-1/3')
                    ->rules('required', 'string', new OnlyLetters(), 'max:255'),

                Text::make(__('Patronic name'), 'customer_patronic_name')
                    ->size('w-1/3')
                    ->rules('required', 'string', new OnlyLetters(), 'max:255'),

                Text::make(__('Old surname (if changed)'), 'old_surname')
                    ->size('w-1/2')
                    ->rules('nullable', 'string', new OnlyLetters(), 'max:255'),

                Date::make(__('Date of birth'), 'born_at')
                    ->size('w-1/2')
                    ->rules('required', 'before_or_equal:today'),

                NovaInputmask::make(__('Phone'), 'phone')
                    ->mask('+(\\9\\93)-99-99-99-99')
                    ->storeRawValue()
                    ->size('w-1/3')
                    ->rules('required', 'integer', 'between:61000000, 71999999'),

                NovaInputmask::make(__('Phone Additional'), 'phone_additional')
                    ->mask('+(\\9\\93)-99-99-99-99')
                    ->storeRawValue()
                    ->size('w-1/3')
                    ->rules('nullable', 'integer', 'between:61000000, 71999999'),

                Select::make(__('Citizenship'), 'citizenship')
                    ->displayUsingLabels()
                    ->searchable()
                    ->options(CountryRepo::values())
                    ->default('TM')
                    ->size('w-1/3')
                    ->rules('required'),

                Text::make(__('Residence (passport)'), 'passport_address')
                    ->size('w-1/2')
                    ->rules('required', 'string', new DowranAgaAllowed(), 'max:255'),

                Text::make(__('Current Residence'), 'real_address')
                    ->size('w-1/2')
                    ->rules('required', 'string', new DowranAgaAllowed(), 'max:255'),

                Text::make(__('Work location and your position'), 'job_location')
                    ->size('w-full')
                    ->rules('required', 'string', new DowranAgaAllowed(), 'max:255'),
            ]),

            new Panel(__('Passport'), [
                Select::make(__('Passport serie'), 'passport_serie')
                    ->displayUsingLabels()
                    ->searchable()
                    ->options(PassportRepo::values())
                    ->size('w-1/3')
                    ->rules('required'),

                Number::make(__('Passport id'), 'passport_id')
                    ->size('w-1/3')
                    ->rules('required', 'numeric', 'digits:6'),

                Date::make(__('Passport date of issue'), 'passport_given_at')
                    ->size('w-1/3')
                    ->rules('required', 'before_or_equal:today'),

                Text::make(__('Passport given by'), 'passport_given_by')
                    ->size('w-1/2')
                    ->rules('required', 'string', new DowranAgaAllowed(), 'max:255'),

                Text::make(__('Born place (passport)'), 'born_place')
                    ->size('w-1/2')
                    ->rules('required', 'string', new DowranAgaAllowed(), 'max:255'),
            ]),

            new Panel(__('Passport files'), [
                Image::make(__('Passport (page 1)'), 'passport_one')
                    ->size('w-1/2')
                    ->deletable(false)
                    ->rules('max:2048', 'mimes:jpg,png,jpeg')
                    ->creationRules('required')
                    ->updateRules('nullable'),

                Image::make(__('Passport (page 2-3)'), 'passport_two')
                    ->size('w-1/2')
                    ->deletable(false)
                    ->rules('max:2048', 'mimes:jpg,png,jpeg')
                    ->creationRules('required')
                    ->updateRules('nullable'),

                Image::make(__('Passport (page 8-9)'), 'passport_three')
                    ->size('w-1/2')
                    ->deletable(false)
                    ->rules('max:2048', 'mimes:jpg,png,jpeg')
                    ->creationRules('required')
                    ->updateRules('nullable'),

                Image::make(__('Passport (page 32)'), 'passport_four')
                    ->size('w-1/2')
                    ->deletable(false)
                    ->rules('max:2048', 'mimes:jpg,png,jpeg')
                    ->creationRules('required')
                    ->updateRules('nullable'),

                NovaCustomHtml::make(__('Data'), 'additional_data')
                    ->html(view('orders.cards.contract-agreement')->render())
                    ->fillUsing(NovaForm::fillEmpty()),
            ]),
        ];
    }

    /**
     * Get the cards available for the request.
     */
    public function cards(NovaRequest $request): array
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     */
    public function filters(NovaRequest $request): array
    {
        return [
            RegionFilter::make()
                ->canSee(fn () => Gate::allows('isAdmin'), auth()->user()),

            new StatusFilter(),
        ];
    }

    /**
     * Get the lenses available for the resource.
     */
    public function lenses(NovaRequest $request): array
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     */
    public function actions(NovaRequest $request): array
    {
        return [];
    }
}
