<?php

namespace Database\Seeders;

use App\Classes\Modules\Accounts\DataTransferObjects\RegistrationObject;
use App\Classes\Modules\Accounts\Services\CreatesUser;
use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject;
use App\Classes\Modules\Addresses\Processors\CreateAddressFromOldAddressProcessor;
use App\Classes\Modules\Addresses\Services\CreatesAddress;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
use App\Classes\Modules\Companies\DataTransferObjects\EmploymentObject;
use App\Classes\Modules\Companies\Processors\AssignEmployeeProcessor;
use App\Classes\Modules\Companies\Processors\CreateCompanyModuleProcessor;
use App\Classes\Modules\Companies\Processors\CreateCompanyProcessor;
use App\Classes\Modules\Companies\Services\ApprovesCompanyConnection;
use App\Classes\Modules\Companies\Services\CreatesCompany;
use App\Classes\Modules\Companies\Services\CreatesCompanyConnection;
use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus;
use App\Classes\Modules\Contacts\DataTransferObjects\ContactObject;
use App\Classes\Modules\Contacts\Processors\CreateContactProcessor;
use App\Classes\Modules\Contacts\Services\CreatesContact;
use App\Classes\ValueObjects\Constants\AddressType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\CompanyType;
use App\Classes\ValueObjects\Constants\BusinessType;

use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\CompanyModule;
use App\Models\User;
use Illuminate\Database\Seeder;

use App\Models\Company;

class LastMileDeliveryTableSeeder extends Seeder
{

    /** @var CreateCompanyProcessor */
    private $createCompanyProcessor;

    /** @var UpdatesCompanyStatus*/
    private $updatesCompanyStatus;

    /** @var CreateCompanyModuleProcessor */
    private $createCompanyModuleProcessor;

    /** @var CreateContactProcessor */
    private $createContactProcessor;

    /** @var CreatesCompanyConnection */
    private $createsCompanyConnection;

    /** @var ApprovesCompanyConnection */
    private $approvesCompanyConnection;

    /** @var CreateAddressFromOldAddressProcessor */
    private $createAddressFromOldAddressProcessor;

    /** @var CreatesAddress */
    private $createsAddress;

    /** @var CreatesCompany */
    private $createsCompany;

    /** @var CreatesContact */
    private $createsContact;

    /** @var CreatesUser */
    private $createsUser;

    /** @var AssignEmployeeProcessor */
    private $assignEmployeeProcessor;

    /**
     * LastMileDeliveryTableSeeder constructor.
     * @param CreateCompanyProcessor $createCompanyProcessor
     * @param UpdatesCompanyStatus $updatesCompanyStatus
     * @param CreateCompanyModuleProcessor $createCompanyModuleProcessor
     * @param CreateContactProcessor $createContactProcessor
     * @param CreatesCompanyConnection $createsCompanyConnection
     * @param ApprovesCompanyConnection $approvesCompanyConnection
     * @param CreateAddressFromOldAddressProcessor $createAddressFromOldAddressProcessor
     * @param CreatesAddress $createsAddress
     * @param CreatesCompany $createsCompany
     * @param CreatesContact $createsContact
     * @param CreatesUser $createsUser
     * @param AssignEmployeeProcessor $assignEmployeeProcessor
     */
    public function __construct(CreateCompanyProcessor $createCompanyProcessor, UpdatesCompanyStatus $updatesCompanyStatus, CreateCompanyModuleProcessor $createCompanyModuleProcessor, CreateContactProcessor $createContactProcessor, CreatesCompanyConnection $createsCompanyConnection, ApprovesCompanyConnection $approvesCompanyConnection, CreateAddressFromOldAddressProcessor $createAddressFromOldAddressProcessor, CreatesAddress $createsAddress, CreatesCompany $createsCompany, CreatesContact $createsContact, CreatesUser $createsUser, AssignEmployeeProcessor $assignEmployeeProcessor)
    {
        $this->createCompanyProcessor = $createCompanyProcessor;
        $this->updatesCompanyStatus = $updatesCompanyStatus;
        $this->createCompanyModuleProcessor = $createCompanyModuleProcessor;
        $this->createContactProcessor = $createContactProcessor;
        $this->createsCompanyConnection = $createsCompanyConnection;
        $this->approvesCompanyConnection = $approvesCompanyConnection;
        $this->createAddressFromOldAddressProcessor = $createAddressFromOldAddressProcessor;
        $this->createsAddress = $createsAddress;
        $this->createsCompany = $createsCompany;
        $this->createsContact = $createsContact;
        $this->createsUser = $createsUser;
        $this->assignEmployeeProcessor = $assignEmployeeProcessor;
    }


    /**
     * Run the database seeds.
     *
     * @return void
     * @throws \App\Classes\Exceptions\AccessForbiddenException
     * @throws \App\Classes\Exceptions\MalformedRequestException
     * @throws \App\Classes\Exceptions\RequestValidationException
     */
    public function run()
    {

        $companies = [
            new CompanyObject('Last Mile Delivery', 'HWT', CompanyType::COMPANY_BUSINESS, ApprovalStatus::APPROVED),
        ];


        foreach ($companies as $companyObject) {

            /** @var Company $company */
            $company = $this->createsCompany->execute($companyObject);

            /** @var CompanyModule $companyModule */
            $companyModule = $this->createCompanyModuleProcessor->execute($company, BusinessType::LAST_MILE_DELIVERY_AGENT);

            $address = new AddressObject('B-39-13, Menara Simfoni, Jalan Simfoni 2, Balakong', 'Block 3730,Persiaran APEC', 1, 15, 432, 43300, AddressType::BILLING, ApprovalStatus::APPROVED);
            $this->createsAddress->execute($companyModule, $address);

            $contact = new ContactObject('Office Number', '01155543194', '', '');
            $this->createsContact->execute($companyModule, $contact);

            $user_object = new RegistrationObject('CQ', 'hywavetech168@gmail.com', 'FIzxqcZFFob7btVLEfWC', 'FIzxqcZFFob7btVLEfWC', RoleTypes::USER, ApprovalStatus::APPROVED);

            /** @var User $user */
            $user = $this->createsUser->execute($user_object);

            $Object = new EmploymentObject($companyModule, $user);
            $this->assignEmployeeProcessor->execute($Object);

            continue;

        }
    }
}
