<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class RenameServiceTables extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
		Schema::table('ab_service', function (Blueprint $table) {
			$table->dropPrimary();
			$table->dropForeign('ab_service_site_id_foreign');
			$table->primary(['id','site_id']);
			$table->dropIndex('ab_service_site_id_foreign');
			$table->dropIndex('ab_service_id_site_id_index');
			$table->datetime('created_at')->nullable()->after('id');
			$table->datetime('updated_at')->nullable()->after('created_at');
			$table->date('invoice_last_at')->nullable()->after('date_last_invoice');
			$table->date('invoice_next_at')->nullable()->after('date_next_invoice');
			$table->date('start_at')->nullable()->after('date_start');
			$table->date('stop_at')->nullable()->after('date_end');
		});

		DB::statement('ALTER TABLE ab_service RENAME TO services');
		DB::statement('ALTER TABLE services MODIFY account_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE services MODIFY account_billing_id int unsigned DEFAULT NULL');
		DB::statement('ALTER TABLE services MODIFY product_id int unsigned NOT NULL');
		DB::statement('UPDATE services SET taxable=1');
		DB::statement('UPDATE services SET active=0 WHERE active IS NULL');
		DB::statement('ALTER TABLE services MODIFY active tinyint(1) NOT NULL,MODIFY suspend_billing tinyint(1) DEFAULT NULL,MODIFY external_billing tinyint(1) DEFAULT NULL,MODIFY taxable tinyint(1) DEFAULT NULL');
		DB::statement('ALTER TABLE services RENAME COLUMN orderby_id TO ordered_by');
		DB::statement('ALTER TABLE services MODIFY ordered_by int unsigned');

		// Convert out dates
		foreach (\App\Models\Service::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->date_orig)
				$o->created_at = \Carbon\Carbon::createFromTimestamp($o->date_orig);
			if ($o->date_last)
				$o->updated_at = \Carbon\Carbon::createFromTimestamp($o->date_last);
			if ($o->date_last_invoice)
				$o->invoice_last_at = \Carbon\Carbon::createFromTimestamp($o->date_last_invoice);
			if ($o->date_next_invoice)
				$o->invoice_next_at = \Carbon\Carbon::createFromTimestamp($o->date_next_invoice);
			if ($o->date_start)
				$o->start_at = \Carbon\Carbon::createFromTimestamp($o->date_start);
			if ($o->date_end)
				$o->stop_at = \Carbon\Carbon::createFromTimestamp($o->date_end);
			$o->save();
		}

		Schema::table('services', function (Blueprint $table) {
			$table->dropColumn(['date_orig','date_last','date_last_invoice','date_next_invoice','date_start','date_end','queue','price_group']);
			$table->foreign(['account_id','site_id'])->references(['id','site_id'])->on('accounts');
			$table->foreign(['product_id','site_id'])->references(['id','site_id'])->on('products');
			$table->foreign(['ordered_by','site_id'])->references(['id','site_id'])->on('users');
			$table->foreign(['site_id'])->references(['site_id'])->on('sites');
		});

		DB::statement('ALTER TABLE service_domains RENAME TO service_domain');
		DB::statement('ALTER TABLE service_emails RENAME TO service_email');

		Schema::table('ab_service_change', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('ab_service_change_site_id_foreign');
			$table->dropIndex('ab_service_change_site_id_foreign');
			$table->dropIndex('ab_service_change_id_site_id_index');
		});

		DB::statement('ALTER TABLE ab_service_change RENAME TO service__change');
		DB::statement('ALTER TABLE service__change MODIFY service_id int unsigned');
		DB::statement('ALTER TABLE service__change MODIFY product_id int unsigned');
		DB::statement('ALTER TABLE service__change MODIFY ordered_by int unsigned');

		Schema::table('service__change', function (Blueprint $table) {
			$table->date('ordered_at')->nullable()->after('ordered_by');
			$table->date('effective_at')->nullable()->after('ordered_at');

			$table->foreign(['product_id','site_id'])->references(['id','site_id'])->on('products');
			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
			$table->foreign(['ordered_by','site_id'])->references(['id','site_id'])->on('users');
		});

		// Convert out dates
		foreach (\App\Models\ServiceChange::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->date_ordered)
				$o->ordered_at = \Carbon\Carbon::createFromTimestamp($o->date_ordered);
			if ($o->date_effective)
				$o->effective_at = \Carbon\Carbon::createFromTimestamp($o->date_effective);
			$o->save();
		}

		DB::statement('ALTER TABLE service__change MODIFY ordered_at int unsigned NOT NULL');
		DB::statement('ALTER TABLE service__change MODIFY effective_at int unsigned NOT NULL');

		Schema::table('service__change', function (Blueprint $table) {
			$table->dropColumn(['date_ordered','date_effective']);
		});

		DB::statement('ALTER TABLE service__generic MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service__generic MODIFY product_id int unsigned DEFAULT NULL');
		DB::statement('UPDATE service__generic SET product_id=NULL WHERE product_id=0');
		Schema::table('service__generic', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('service__generic_site_id_foreign');
			$table->dropIndex('service__generic_site_id_foreign');
			$table->dropIndex('service__generic_id_site_id_index');

			$table->foreign(['product_id','site_id'])->references(['id','site_id'])->on('products');
			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
		});

		DB::statement('ALTER TABLE service_domain MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_domain MODIFY domain_tld_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_domain MODIFY domain_registrar_id int unsigned DEFAULT NULL');
		DB::statement('ALTER TABLE service_domain MODIFY domain_name varchar(128) NOT NULL');
		DB::statement('ALTER TABLE service_domain RENAME COLUMN domain_tld_id TO tld_id');

		Schema::table('service_domain', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('service_domains_site_id_foreign');
			$table->dropIndex('service_domains_site_id_foreign');
			$table->dropIndex('service_domains_id_site_id_index');

			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
			$table->foreign(['tld_id'])->references(['id'])->on('tlds');

			$table->date('expire_at')->nullable()->after('domain_expire');
		});

		// Convert out dates
		foreach (\App\Models\Service\Domain::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->domain_expire)
				$o->expire_at = \Carbon\Carbon::createFromTimestamp($o->domain_expire);
			$o->save();
		}

		Schema::table('service_domain', function (Blueprint $table) {
			$table->dropColumn(['registrar_lastsync','domain_expire']);
		});

		DB::statement('ALTER TABLE service_email DROP PRIMARY KEY,ADD PRIMARY KEY (id,site_id)');

		Schema::table('service_email', function (Blueprint $table) {
			$table->unique(['domain_name','tld_id']);
			$table->dropForeign('service_emails_site_id_foreign');
			$table->dropForeign('service_emails_service_id_foreign');
			$table->dropForeign('service_emails_tld_id_foreign');

			$table->foreign(['tld_id'])->references(['id'])->on('tlds');
			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
		});

		DB::statement('ALTER TABLE ab_service__hosting RENAME TO service_host');
		DB::statement('ALTER TABLE service_host RENAME COLUMN domain_tld_id TO tld_id');
		DB::statement('ALTER TABLE service_host MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_host MODIFY tld_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_host MODIFY host_server_id int unsigned DEFAULT NULL');

		DB::statement('ALTER TABLE service_host MODIFY domain_name varchar(128) NOT NULL');

		Schema::table('service_host', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('ab_service__hosting_site_id_foreign');
			$table->dropIndex('ab_service__hosting_site_id_foreign');
			$table->dropIndex('ab_service__hosting_id_site_id_index');

			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
			$table->foreign(['tld_id'])->references(['id'])->on('tlds');

			$table->date('expire_at')->nullable()->after('host_expire');
		});

		// Convert our dates
		foreach (\App\Models\Service\Host::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->server_data && (strlen($o->server_data) > 8) && gzuncompress($o->server_data))
				$o->server_data = NULL;
			if ($o->host_expire)
				$o->expire_at = \Carbon\Carbon::createFromTimestamp($o->host_expire);
			$o->save();
		}

		Schema::table('service_host', function (Blueprint $table) {
			$table->dropColumn(['host_expire','server_data_date']);
		});

		DB::statement('ALTER TABLE product_broadband RENAME COLUMN supplier_broadband_id TO supplier_item_id');
		DB::statement('ALTER TABLE product_domain RENAME COLUMN supplier_domain_id TO supplier_item_id');
		DB::statement('ALTER TABLE product_email RENAME COLUMN supplier_email_id TO supplier_item_id');
		DB::statement('ALTER TABLE product_host RENAME COLUMN supplier_host_id TO supplier_item_id');
		DB::statement('ALTER TABLE product_ssl RENAME COLUMN supplier_ssl_id TO supplier_item_id');
		DB::statement('ALTER TABLE product_generic RENAME COLUMN supplier_generic_id TO supplier_item_id');

		DB::statement('ALTER TABLE product_voip RENAME TO product_phone');
		DB::statement('ALTER TABLE product_phone RENAME COLUMN supplier_voip_id TO supplier_item_id');

		Schema::table('product_phone', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('product_voip_supplier_voip_id_site_id_foreign');
			$table->dropForeign('product_voip_site_id_foreign');
			$table->dropIndex('product_voip_supplier_voip_id_site_id_foreign');
			$table->dropIndex('product_voip_site_id_foreign');
			$table->dropIndex('product_voip_id_site_id_index');
		});

		DB::statement('ALTER TABLE supplier_voip RENAME TO supplier_phone');
		Schema::table('supplier_phone', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->dropForeign('supplier_voip_supplier_detail_id_site_id_foreign');
			$table->dropForeign('supplier_voip_site_id_foreign');
			$table->dropIndex('supplier_voip_id_site_id_index');

			$table->foreign(['supplier_detail_id','site_id'])->references(['id','site_id'])->on('supplier_details');

			$table->string('technology')->nullable();
		});

		Schema::table('product_phone', function (Blueprint $table) {
			$table->foreign(['supplier_item_id','site_id'])->references(['id','site_id'])->on('supplier_phone');

			$table->string('technology')->nullable();
		});

		DB::statement('ALTER TABLE ab_service__voip RENAME TO service_phone');
		DB::statement('ALTER TABLE service_phone MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_phone MODIFY service_number varchar(10) NOT NULL');
		DB::statement('ALTER TABLE service_phone MODIFY site_id int unsigned NOT NULL');

		Schema::table('service_phone', function (Blueprint $table) {
			$table->primary(['id','site_id']);
			$table->date('connect_at')->nullable()->after('contract_term');
			$table->date('expire_at')->nullable()->after('connect_at');
			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
			$table->string('technology')->nullable();
		});

		DB::statement('ALTER TABLE service_phone MODIFY id int unsigned auto_increment');

		// Convert our dates
		foreach (\App\Models\Service\Phone::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->service_connect_date)
				$o->connect_at = \Carbon\Carbon::createFromTimestamp($o->service_connect_date);
			if ($o->getRawOriginal('contract_term') === 0)
				$o->contract_term = NULL;
			if ($o->service_contract_date && $o->getRawOriginal('contract_term'))
				$o->expire_at = \Carbon\Carbon::createFromTimestamp($o->service_contract_date)->addMonths($o->getRawOriginal('contract_term'));
			$o->save();
		}

		Schema::table('service_phone', function (Blueprint $table) {
			$table->dropColumn(['service_connect_date','service_contract_date','contract_term']);
		});

		DB::statement('ALTER TABLE ab_service__adsl RENAME TO service_broadband');
		DB::statement('ALTER TABLE service_broadband MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_broadband MODIFY service_stats_collect tinyint(1) DEFAULT NULL');
		DB::statement('ALTER TABLE service_broadband RENAME COLUMN service_stats_lastupdate TO service_stats_at');
		DB::statement('ALTER TABLE service_broadband RENAME COLUMN provided_adsl_plan_id TO provided_supplier_broadband_id');
		DB::statement('ALTER TABLE service_broadband MODIFY provided_supplier_broadband_id int unsigned DEFAULT NULL');
		// @todo drop column provided_adsl_plan_id

		Schema::table('service_broadband', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);
			$table->date('connect_at')->nullable()->after('contract_term');
			$table->date('expire_at')->nullable()->after('connect_at');
			$table->ipAddress('ip6address')->nullable()->after('ipaddress');
			$table->string('technology')->nullable();

			$table->dropForeign('ab_service__adsl_site_id_foreign');
			$table->dropIndex('ab_service__adsl_site_id_foreign');
			$table->dropIndex('ab_service__adsl_id_site_id_index');

			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
			$table->foreign(['provided_supplier_broadband_id','site_id'])->references(['id','site_id'])->on('supplier_broadband');
		});

		// Convert our dates
		foreach (\App\Models\Service\Broadband::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
			if ($o->service_connect_date)
				$o->connect_at = \Carbon\Carbon::createFromTimestamp($o->service_connect_date);
			if ($o->getRawOriginal('contract_term') === 0)
				$o->contract_term = NULL;
			if ($o->service_contract_date && $o->getRawOriginal('contract_term'))
				$o->expire_at = \Carbon\Carbon::createFromTimestamp($o->service_contract_date)->addMonths($o->getRawOriginal('contract_term'));
			$o->save();
		}

		Schema::table('service_broadband', function (Blueprint $table) {
			$table->dropColumn(['service_connect_date','service_contract_date','contract_term']);
		});

		Schema::table('supplier_broadband', function (Blueprint $table) {
			$table->string('technology')->nullable();
		});

		DB::select("UPDATE services SET model='App\\\\Models\\\\Service\\\\Phone' where model='App\\\\Models\\\\Service\\\\Voip'");
		DB::select("UPDATE products SET model='App\\\\Models\\\\Product\\\\Phone' where model='App\\\\Models\\\\Product\\\\Voip'");

		DB::statement('ALTER TABLE ab_service__ssl RENAME TO service_ssl');
		DB::statement('ALTER TABLE service_ssl MODIFY service_id int unsigned NOT NULL');
		DB::statement('ALTER TABLE service_ssl MODIFY ssl_ca_id int unsigned DEFAULT NULL');

		Schema::table('service_ssl', function (Blueprint $table) {
			$table->dropPrimary();
			$table->primary(['id','site_id']);

			$table->dropForeign('ab_service__ssl_site_id_foreign');
			$table->dropIndex('ab_service__ssl_site_id_foreign');
			$table->dropIndex('ab_service__ssl_id_site_id_index');

			$table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
		});

		foreach (DB::select('SELECT * FROM products where model="App\\\\Models\\\\Product\\\\SSL"') as $o) {
			DB::select('UPDATE services set model="App\\\\Models\\\\Service\\\\SSL" WHERE product_id='.$o->id);
		};

		Schema::table('products', function (Blueprint $table) {
			$table->dropForeign(['site_id']);
			$table->foreign(['site_id'])->references(['site_id'])->on('sites');
		});
	}

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
		abort(500,'Cant go back');
    }
}