<?php

namespace Ignite\Core\Database\Seeders;

use Ignite\Activity\Entities\Activity;
use Ignite\Activity\Entities\Offer;
use Ignite\Activity\Entities\Submission;
use Ignite\Activity\Entities\SubmissionStatus;
use Ignite\Activity\Entities\Type;
use Ignite\Core\Database\Seeders\AbstractSeeder;
use Ignite\Core\Entities\Group;
use Ignite\Core\Entities\Transaction;
use Ignite\Core\Entities\User;
use Ignite\Core\Entities\Participant;
use Ignite\Core\Entities\UserGroup;
use Illuminate\Database\Seeder;
use Nwidart\Modules\Module;

/**
 * php artisan db:seed --class="Ignite\Core\Database\Seeders\DemoSeeder"
 * php artisan module:seed Core
 *
 * @todo: should extend AbstractSeeder
 */
class DemoSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $userGroup = Group::where('key', 'participant')->pluck('id')->toArray();
        /* List of all modules
         * -------------------------------------------------- */
        $modules = collect(\Nwidart\Modules\Facades\Module::all())
            ->filter(function (\Nwidart\Modules\Module $module) {
                return $module->isEnabled();
            })
            ->filter();

        $activityType = null;
        $activityOffer = null;
        if ($modules->has('Activity')) {
            $activityType = factory(Type::class)->create([
                'label' => 'Demo Activity',
                'code' => 'sales',
            ]);

            $activityOffer = factory(Offer::class)
                ->create([
                    'type_id' => $activityType->id,
                    'label' => 'General',
                    'code' => 'general',
                    'related_name' => 'GeneralSales',
                    'status' => 1,
                    'is_redeemable' => 1,
                    'meta' => [],
                    'translations' => '[{"en": {"label": "Submit Activities", "description": "Submit your activities and earn rewards!"}}]',
                    'sequence' => 1,
                ]);
        }

        $registrationDate = new \DateTime(date('Y-m-d 00:00:00'));
        $registrationDate->sub(new \DateInterval('P180D'));
        factory(Participant::class, 100)
            ->create([
                'type' => 'Participant',
                'internal' => User::TYPE_PARTICIPANT,
                'created_at' => $registrationDate->format('Y-m-d H:i:s'),
                'updated_at' => $registrationDate->format('Y-m-d H:i:s'),
            ])
            ->each(function ($participant) use ($userGroup, $modules, $activityType, $activityOffer, $registrationDate) {
                $participant->user->internal = User::TYPE_PARTICIPANT;
                $participant->user->created_at = $registrationDate->format('Y-m-d H:i:s');
                $participant->user->updated_at = $registrationDate->format('Y-m-d H:i:s');
                $participant->user->save();

                $participant->user->groups()->attach($userGroup);

                if ($modules->has('Activity')) {
                    // -- You can see factories, or you can do create() to create your activity
                    // -- and submission through the standard process.
                    // $activity = resolve(ActivitySubmissionRepository::class)
                    //     ->create($activityOffer, $data, $participant->user);

                    factory(Activity::class, rand(0, 10))
                        ->create([
                            'type_id' => $activityType->id,
                            'offer_id' => $activityOffer->id,
                            'submitter_id' => $participant->user_id,
                            'meta' => [],
                        ])
                        ->each(function ($activity) use ($participant) {
                            $values = [50, 100, 150];
                            $valueKey = array_rand($values);

                            $maxDate = new \DateTime(date('Y-m-d H:i:s'));
                            $minDate = new \DateTime(date('Y-m-d 00:00:00'));
                            $minDate->sub(new \DateInterval('P175D'));

                            $date = rand(strtotime($minDate->format('Y-m-d H:i:s')), strtotime($maxDate->format('Y-m-d H:i:s')));
                            $activitySubmission = factory(Submission::class)
                                ->create([
                                    'activity_id' => $activity->id,
                                    'user_id' => $participant->user_id,
                                    'status' => 'pending',
                                    'value' => $values[$valueKey],
                                    'created_at' => date('Y-m-d H:i:s', $date),
                                    'updated_at' => date('Y-m-d H:i:s', $date),
                                ]);

                            if (rand(0, 1) && $activitySubmission->status == 'pending') {
                                $statuses = ['approved', 'declined', 'issued'];
                                $statusKey = array_rand($statuses);
                                $activitySubmission->status = $statuses[$statusKey];
                                $activitySubmission->save();
                            }

                            if ($activitySubmission->status == 'issued') {
                                // add 7 days to the date above
                                $transactionDate = new \DateTime($activitySubmission->created_at);
                                $transactionDate->add(new \DateInterval('P7D'));

                                $descriptionReasons = ['product sold', 'confirmed activity'];
                                $descriptionReasonKey = array_rand($descriptionReasons);

                                $participant->transactions()->save(
                                    factory(Transaction::class)
                                        ->make(
                                            [
                                                'type' => 'EARNED',
                                                'transaction_date' => $transactionDate->format('Y-m-d H:i:s'),
                                                'tax_date' => $transactionDate->format('Y-m-d H:i:s'),
                                                'description' => 'Earned for '.$descriptionReasons[$descriptionReasonKey],
                                                'notes' => '',
                                                'value' => $activitySubmission->value,
                                                'related_type' => 'Ignite\Activity\Entities\Submission',
                                                'related_id' => $activity->id,
                                            ]
                                        )
                                );
                            }

                            // -- changing status could be done through the normal process --
                            // $submission = resolve(ActivitySubmissionRepository::class)
                            //     ->changeStatus(
                            //         $activity->submission->getKey(),
                            //         'approved',
                            //         'Lorem ipsum dolor',
                            //         $participant->user
                            //     );
                        });

                    $latestSubmissionDate = Submission::where('user_id', $participant->user_id)->orderBy('created_at', 'desc')->first();
                    if (!is_null($latestSubmissionDate)) {
                        $participant->user->last_login_at = $latestSubmissionDate->created_at;
                        $participant->user->save();
                    }
                }
            });
    }
}
