<?php

use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

use App\Advert;
use App\User;
use App\Category;
use App\Region;
use App\City;
use App\Page;
use App\Dialogue;
use App\Review;
use App\Company;
use App\Field;
use App\FieldType;
use App\FieldVariant;
use App\Feature;
use \App\Tariff;

class DatabaseTestingSeeder extends Seeder {

  public function run()
  {
    $this->call('ModulesTableSeeder');
    $this->call('HighlightColorTableSeeder');
    $this->call('OperationTypeTableSeeder');
    $this->call('CategoryTableSeeder');
    $this->call('FlagshipCategoryTableSeeder');
    $this->call('NotificationTypesTableSeeder');
    $this->call('UsersTestTableSeeder');
    $this->call('AdvertsTestTableSeeder');
    $this->call('CitiesTestTableSeeder');
    $this->call('RegionsTestTableSeeder');
    $this->call('PageTableSeeder');
    $this->call('PagesTestTableSeeder');
    $this->call('RolesTableSeeder');
    $this->call('RelationsTestTableSeeder');
    $this->call('ReviewsTestTableSeeder');
    $this->call('CompaniesTestTableSeeder');
    $this->call('FieldTypesTableSeeder');
    $this->call('AdditionalFieldsTestTableSeeder');
    $this->call('FeaturesTestTableSeeder');
    $this->call('TariffTestTableSeeder');
  }

}

class UsersTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('users')->truncate();
    DB::table('companies')->truncate();

    User::create(
      [
        'city_id' => 10, 'login' => 'admin', 'email' => 'admin@timbse.com',
        'password' => bcrypt('159753'), 'name' => 'Суперпользователь сайта', 'phone' => '8-123-444-55-55',
        'add_phone' => '', 'score' => 1000000, 'rate' => 0
      ]
    )->setAllNotifications();
    User::create(
      [
        'city_id' => 10, 'login' => 'testuser', 'email' => 'testuser@timbse.loc',
        'password' => bcrypt('159753'), 'name' => 'Иванов Иван Иванович', 'phone' => '87771234567',
        'add_phone' => '87771234568', 'score' => 1000, 'rate' => 0
      ]
    )->setAllNotifications();

    $CompanyUser = User::create([
        'city_id' => 10, 'login' => 'testcompany', 'email' => 'testcompany@timbse.loc',
        'password' => bcrypt('159753'), 'name' => 'Test company inc.', 'phone' => '87771234567',
        'add_phone' => '87771234568', 'score' => 1000, 'rate' => 0
      ]);

    $faker = Faker::create('ru_RU');

    $CompanyUser->setAllNotifications();
    $Company = new Company;

    $Company->business_id = 1;
    $Company->name        = $faker->company;
    $Company->address     = $faker->address;
    $Company->phone       = $faker->phoneNumber;
    $Company->add_phone   = $faker->phoneNumber;
    $Company->email       = $faker->companyEmail;
    $Company->work_time   = $faker->dateTimeBetween();
    $Company->website     = $faker->url;
    $Company->save();

    $Company->user()->associate($CompanyUser);
    $Company->save();

    for($i=0; $i<15; $i++)
    {
      User::create(
        [
          'city_id' => $faker->numberBetween(1, 10),
          'login' => $faker->unique()->userName,
          'email' => $faker->email,
          'password' => bcrypt($faker->randomNumber()),
          'name' => $faker->name,
          'phone' => $faker->phoneNumber,
          'score' => $faker->numberBetween(100, 5000)
        ]
      )->setAllNotifications();
    }
  }

}

class AdvertsTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('adverts')->truncate();

    $faker = Faker::create('ru_RU');

    for($i=0; $i<50; $i++)
    {
      $Advert = new Advert;

      $Advert->category_id = $faker->numberBetween(10, 40);
      $Advert->city_id = $faker->numberBetween(1, 20);
      $Advert->user_id = $faker->numberBetween(5, 15);
      $Advert->title = $faker->sentence;
      $Advert->slug = str_slug($faker->sentence);
      $Advert->address = $faker->address;
      $Advert->body = $faker->realText(500);
      $Advert->return_conditions = $faker->text();
      $Advert->price = $faker->numberBetween(500, 15000);
      $Advert->delivery_by_city = $faker->boolean();
      $Advert->delivery_by_country = $faker->boolean();
      $Advert->cash = $faker->boolean();
      $Advert->card = $faker->boolean();
      $Advert->cash_on_delivery = $faker->boolean();

      $highlight = $faker->boolean();
      $enforce   = $faker->boolean();

      $Advert->is_highlighted = $highlight;
      $Advert->is_enforced    = $enforce;

      if($highlight)
        $Advert->highlight_color()->associate(\App\HighlightColor::find($faker->numberBetween(1,2)));

      if($highlight || $enforce)
        $Advert->payment_end = date("Y-m-d H:i:s", time()+20*86400);

      $Advert->save();

      unset($Advert);
    }
  }

}

class CitiesTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('cities')->truncate();

    $faker = Faker::create('ru_RU');

    for($i=0; $i<20; $i++)
    {
      City::create([
        'region_id' => $faker->numberBetween(1, 30),
        'name' => $faker->city
      ]);
    }
  }

}

class RegionsTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('regions')->truncate();

    $faker = Faker::create('ru_RU');

    for($i=0; $i<30; $i++)
    {
      Region::create([
        'name' => $faker->country
      ]);
    }
  }

}

class PagesTestTableSeeder extends Seeder {

  public function run()
  {
    $Faker = Faker::create('ru_RU');

    for($i=0; $i<5; $i++)
    {
      Page::create([
        'title' => $Faker->sentence,
        'slug'  => $Faker->unique()->word,
        'content' => $Faker->realText(500)
      ]);
    }
  }

}

class RelationsTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('user_blocked')->truncate();
    DB::table('user_events')->truncate();
    DB::table('user_favorites')->truncate();
    DB::table('user_subscribers')->truncate();
    DB::table('messages')->truncate();
    DB::table('dialogues')->truncate();
    DB::table('dialogue_user')->truncate();

    $Admin = User::find(1);
    $Faker = Faker::create('ru_RU');

    $Admin->blacklist()->save(User::find(3));
    $Admin->blacklist()->save(User::find(4));

    $UserWithAdverts = User::has('adverts')->get();

    foreach($UserWithAdverts as $user)
    {
      $Admin->usersubs()->save($user);

      foreach($user->adverts as $advert)
      {
        $Admin->dashboard()->save($advert);
      }
    }

    for($i=0; $i<5; $i++)
    {
      $Admin->favorites()->save(Advert::find(mt_rand(1,50)));
    }

    $Recipient = User::find(2);
    $Dialogue  = Dialogue::create([]);

    for($i=0; $i<3; $i++)
    {
      $Message = new \App\Message();

      $Message->content = $Faker->realText();
      $Message->user()->associate($Admin);

      $Message->save();

      $Dialogue->messages()->save($Message);
      $Dialogue->last_message()->associate($Message);
      $Dialogue->users()->sync([$Admin->id, $Recipient->id]);
      $Dialogue->save();

      sleep(1);

      $ResponseMessage = new \App\Message();

      $ResponseMessage->content = $Faker->realText();
      $ResponseMessage->user()->associate($Recipient);

      $ResponseMessage->save();

      $Dialogue->messages()->save($ResponseMessage);
      $Dialogue->last_message()->associate($ResponseMessage);
      $Dialogue->users()->sync([$Admin->id, $Recipient->id]);
      $Dialogue->save();

      sleep(1);
    }

    // Добавляем новый диалог

    $from_id = $Faker->numberBetween(3, 5);
    $to_id   = $Faker->numberBetween(6, 8);

    $Message = new \App\Message();
    $Dialogue = new \App\Dialogue();
    $Dialogue->save();

    $Message->content = $Faker->realText();
    $Message->user()->associate(User::find($from_id));
    $Message->save();

    $Dialogue->messages()->save($Message);
    $Dialogue->last_message()->associate($Message);
    $Dialogue->users()->sync([$from_id, $to_id]);
    $Dialogue->save();

    sleep(1);

    $ResponseMessage = new \App\Message();

    $ResponseMessage->content = $Faker->realText();
    $ResponseMessage->user()->associate(User::find($to_id));
    $ResponseMessage->save();

    $Dialogue->messages()->save($ResponseMessage);
    $Dialogue->last_message()->associate($ResponseMessage);
    $Dialogue->users()->sync([$from_id, $to_id]);
    $Dialogue->save();
  }

}

class ReviewsTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('reviews')->truncate();

    $Faker = Faker::create('ru_RU');

    $User = User::find(1);

    for($i=0; $i<10; $i++)
    {
      $Review = Review::create([
        'content' => $Faker->realText(),
        'rate'    => $Faker->numberBetween(1,5)
      ]);

      $User->reviews()->save($Review);
      $Review->from()->associate(User::find($Faker->numberBetween(2,15)));
      $Review->save();
    }

    $User->updateRate();
  }

}

class CompaniesTestTableSeeder extends Seeder {

  public function run()
  {
    $Faker = Faker::create('ru_RU');

    for($i=0; $i<10; $i++)
    {
      $User = User::create([

        'login'     => $Faker->userName,
        'email'     => $Faker->email,
        'password'  => bcrypt($Faker->randomDigit),
        'avatar'    => $Faker->imageUrl(200, 200, 'business'),
        'name'      => $Faker->name,
        'phone'     => $Faker->phoneNumber,
        'add_phone' => $Faker->phoneNumber,
        'about'     => $Faker->realText(),
        'score'     => $Faker->numberBetween(1000, 5000)

      ]);

      $Company = new Company;
      $Company->business_id = 1;
      $Company->name        = $Faker->company;
      $Company->address     = $Faker->address;
      $Company->phone       = $Faker->phoneNumber;
      $Company->add_phone   = $Faker->phoneNumber;
      $Company->email       = $Faker->companyEmail;
      $Company->work_time   = $Faker->dateTimeBetween();
      $Company->website     = $Faker->url;
      $Company->save();

      $Company->user()->associate($User);
      $Company->save();

    }
  }

}

class AdditionalFieldsTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('category_field')->truncate();
    DB::table('fields')->truncate();
    DB::table('field_variants')->truncate();

    $Faker = Faker::create('ru_RU');

    $Categories = Category::all();

    // Создание дополнительных полей всех типов
    for($i=0; $i<6; $i++)
    {
      $Field = Field::create(
        [
          'name'        => $Faker->word,
          'description' => $Faker->realText()
        ]
      );

      $Field->type()->associate(FieldType::find($i+1));
      $Field->save();

      foreach($Categories as $Category)
      {
        $Category->fields()->save($Field);
        $Category->fields()->updateExistingPivot($i+1, ['searchable'=>true]);
      }

    }

    $variantFields =
      [
        Field::where('type_id','=',FieldType::getCheckboxType())->first(),
        Field::where('type_id','=',FieldType::getRadioType())->first(),
        Field::where('type_id','=',FieldType::getSelectType())->first()
      ];

    // Добавление вариантов для каждого типа полей
    foreach($variantFields as $CurrentField)
    {
      for($v=0; $v<5; $v++)
      {
        $Variant = FieldVariant::create(
          [
            'value' => $Faker->word
          ]);

        $Variant->field()->associate($CurrentField);
        $Variant->category()->associate($Category);
        $Variant->save();
      }
    }
  }

}

class FeaturesTestTableSeeder extends Seeder {

  public function run()
  {
    DB::table('features')->truncate();
    $Faker = Faker::create('ru_RU');

    $Adverts = Advert::all();

    foreach($Adverts as $Advert)
    {
      $Category = $Advert->category;

      $categoryFields = $Category->fields;
      while($categoryFields->count() > 0)
      {
        $field   = $categoryFields->pop();
        $Feature = new Feature;

        $value = '';
        $type  = $field->type->getTypeName();

        switch($type)
        {
          case 'text':

            $value = $Faker->word;

            break;
          case 'textarea':

            $value = $Faker->realText();

            break;
          case 'number':

            $value = $Faker->randomNumber();

            break;
          case 'checkbox':
          case 'radio':
          case 'select':

            $value = $Faker->numberBetween(1, $field->variants->count());

            break;
        }

        $Feature->saveValue($value, $type);
        $Feature->field()->associate($field);
        $Feature->advert()->associate($Advert);
        $Feature->save();
      }

      $Advert->payment_end = date("Y-m-d H:i:s", time()+10*86400);
      $Advert->save();
    }

  }

}

class TariffTestTableSeeder extends Seeder {

  public function run()
  {
    $Faker = Faker::create('ru_RU');

    foreach(Tariff::all() as $Tariff)
    {
      $Tariff->cost = $Faker->numberBetween(100, 1000);
      $Tariff->save();
    }

  }
}