<?php

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

class SyncAllTablesWithCanonicalSchema extends Migration
{
    public function up()
    {
        // USERS TABLE
        Schema::table('users', function (Blueprint $table) {
            if (!Schema::hasColumn('users', 'extension')) {
                $table->smallInteger('extension')->unsigned()->default(201)->after('mobile');
            }
            if (!Schema::hasColumn('users', 'account_type')) {
                $table->enum('account_type', ['local','ldap','oauth'])->default('local')->after('extension');
            }
            if (!Schema::hasColumn('users', 'points')) {
                $table->integer('points')->default(0)->after('suspended');
            }
            if (!Schema::hasColumn('users', 'suspended_time')) {
                $table->timestamp('suspended_time')->nullable()->after('suspended');
            }
            if (!Schema::hasColumn('users', 'last_login')) {
                $table->timestamp('last_login')->nullable()->after('suspended_time');
            }
            if (!Schema::hasColumn('users', 'oauth_type')) {
                $table->enum('oauth_type', ['customer','site_user'])->nullable()->after('last_login');
            }
            if (!Schema::hasColumn('users', 'oauth_id')) {
                $table->unsignedBigInteger('oauth_id')->nullable()->after('oauth_type');
            }
            if (!Schema::hasColumn('users', 'oauth_billing')) {
                $table->tinyInteger('oauth_billing')->default(0)->after('oauth_id');
            }
            if (!Schema::hasColumn('users', 'remember_token')) {
                $table->string('remember_token', 100)->nullable()->after('oauth_billing');
            }
            if (!Schema::hasColumn('users', 'mute_sounds')) {
                $table->tinyInteger('mute_sounds')->default(0)->after('remember_token');
            }
            if (!Schema::hasColumn('users', 'role')) {
                $table->string('role', 128)->default('')->after('mute_sounds');
            }
            if (!Schema::hasColumn('users', 'asana_private_api_key')) {
                $table->string('asana_private_api_key', 200)->nullable()->after('role');
            }
            if (!Schema::hasColumn('users', 'repair_target')) {
                $table->integer('repair_target')->nullable()->after('asana_private_api_key');
            }
            if (!Schema::hasColumn('users', 'email_verified_at')) {
                $table->timestamp('email_verified_at')->nullable()->after('repair_target');
            }
        });
        $connection = DB::connection()->getDatabaseName();
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'users'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('users_username_unique', $indexNames)) {
            Schema::table('users', function (Blueprint $table) {
                $table->unique('username', 'users_username_unique');
            });
        }
        if (!in_array('users_email_unique', $indexNames)) {
            Schema::table('users', function (Blueprint $table) {
                $table->unique('email', 'users_email_unique');
            });
        }
        if (!in_array('users_active_index', $indexNames)) {
            Schema::table('users', function (Blueprint $table) {
                $table->index('active', 'users_active_index');
            });
        }
        if (!in_array('users_account_type_index', $indexNames)) {
            Schema::table('users', function (Blueprint $table) {
                $table->index('account_type', 'users_account_type_index');
            });
        }

        // GROUPS TABLE
        Schema::table('groups', function (Blueprint $table) {
            if (!Schema::hasColumn('groups', 'description')) {
                $table->text('description')->nullable()->after('name');
            }
        });
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'groups'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('groups_name_unique', $indexNames)) {
            Schema::table('groups', function (Blueprint $table) {
                $table->unique('name', 'groups_name_unique');
            });
        }

        // PERMISSIONS TABLE
        Schema::table('permissions', function (Blueprint $table) {
            if (!Schema::hasColumn('permissions', 'description')) {
                $table->text('description')->nullable()->after('name');
            }
        });
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'permissions'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('permissions_name_unique', $indexNames)) {
            Schema::table('permissions', function (Blueprint $table) {
                $table->unique('name', 'permissions_name_unique');
            });
        }

        // GROUP_USER TABLE
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'group_user'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('group_user_user_id_foreign', $indexNames)) {
            Schema::table('group_user', function (Blueprint $table) {
                $table->index('user_id', 'group_user_user_id_foreign');
            });
        }

        // GROUP_PERMISSIONS TABLE
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'group_permissions'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('group_permissions_permission_id_foreign', $indexNames)) {
            Schema::table('group_permissions', function (Blueprint $table) {
                $table->index('permission_id', 'group_permissions_permission_id_foreign');
            });
        }

        // CLIENTS TABLE
        Schema::table('clients', function (Blueprint $table) {
            if (!Schema::hasColumn('clients', 'primary_site')) {
                $table->unsignedBigInteger('primary_site')->nullable()->after('name');
            }
            if (!Schema::hasColumn('clients', 'primary_contact')) {
                $table->unsignedBigInteger('primary_contact')->nullable()->after('primary_site');
            }
            if (!Schema::hasColumn('clients', 'contract_id')) {
                $table->unsignedBigInteger('contract_id')->nullable()->after('primary_contact');
            }
            if (!Schema::hasColumn('clients', 'contract_price')) {
                $table->decimal('contract_price', 10, 2)->default(0.00)->after('contract_id');
            }
            if (!Schema::hasColumn('clients', 'contract_start_date')) {
                $table->timestamp('contract_start_date')->nullable()->after('contract_price');
            }
            if (!Schema::hasColumn('clients', 'contract_end_date')) {
                $table->timestamp('contract_end_date')->nullable()->after('contract_start_date');
            }
            if (!Schema::hasColumn('clients', 'sla_id')) {
                $table->unsignedBigInteger('sla_id')->nullable()->after('contract_end_date');
            }
            if (!Schema::hasColumn('clients', 'website')) {
                $table->string('website', 128)->default('')->after('sla_id');
            }
            if (!Schema::hasColumn('clients', 'kashflow_id')) {
                $table->unsignedBigInteger('kashflow_id')->nullable()->after('website');
            }
            if (!Schema::hasColumn('clients', 'xero_id')) {
                $table->string('xero_id', 255)->nullable()->after('kashflow_id');
            }
            if (!Schema::hasColumn('clients', 'enable_feedback')) {
                $table->tinyInteger('enable_feedback')->default(0)->after('xero_id');
            }
            if (!Schema::hasColumn('clients', 'flagged')) {
                $table->tinyInteger('flagged')->default(0)->after('enable_feedback');
            }
            if (!Schema::hasColumn('clients', 'followup_exempt')) {
                $table->tinyInteger('followup_exempt')->default(0)->after('flagged');
            }
            if (!Schema::hasColumn('clients', 'blind_notes')) {
                $table->text('blind_notes')->nullable()->after('followup_exempt');
            }
            if (!Schema::hasColumn('clients', 'sugarcrm_id')) {
                $table->string('sugarcrm_id', 255)->nullable()->after('blind_notes');
            }
            if (!Schema::hasColumn('clients', 'contract_monthly_allowance')) {
                $table->integer('contract_monthly_allowance')->nullable()->after('sugarcrm_id');
            }
            if (!Schema::hasColumn('clients', 'deleted_at')) {
                $table->timestamp('deleted_at')->nullable()->after('updated_at');
            }
            if (!Schema::hasColumn('clients', 'onSite')) {
                $table->tinyInteger('onSite')->default(0)->after('contract_monthly_allowance');
            }
            if (!Schema::hasColumn('clients', 'emergency')) {
                $table->tinyInteger('emergency')->default(0)->after('onSite');
            }
            if (!Schema::hasColumn('clients', 'recurring')) {
                $table->tinyInteger('recurring')->default(0)->after('emergency');
            }
            if (!Schema::hasColumn('clients', 'contractStart')) {
                $table->timestamp('contractStart')->nullable()->after('recurring');
            }
            if (!Schema::hasColumn('clients', 'isRecurring')) {
                $table->tinyInteger('isRecurring')->default(0)->after('contractStart');
            }
        });
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'clients'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('clients_name_unique', $indexNames)) {
            Schema::table('clients', function (Blueprint $table) {
                $table->unique('name', 'clients_name_unique');
            });
        }
        if (!in_array('clients_contract_id_index', $indexNames)) {
            Schema::table('clients', function (Blueprint $table) {
                $table->index('contract_id', 'clients_contract_id_index');
            });
        }
        if (!in_array('clients_sla_id_index', $indexNames)) {
            Schema::table('clients', function (Blueprint $table) {
                $table->index('sla_id', 'clients_sla_id_index');
            });
        }
        if (!in_array('clients_deleted_at_index', $indexNames)) {
            Schema::table('clients', function (Blueprint $table) {
                $table->index('deleted_at', 'clients_deleted_at_index');
            });
        }

        // CUSTOMERS TABLE
        Schema::table('customers', function (Blueprint $table) {
            if (!Schema::hasColumn('customers', 'phone2')) {
                $table->string('phone2', 15)->nullable()->after('phone');
            }
            if (!Schema::hasColumn('customers', 'address')) {
                $table->string('address', 128)->nullable()->after('mobile');
            }
            if (!Schema::hasColumn('customers', 'address2')) {
                $table->string('address2', 128)->nullable()->after('address');
            }
            if (!Schema::hasColumn('customers', 'town')) {
                $table->string('town', 128)->default('')->after('address2');
            }
            if (!Schema::hasColumn('customers', 'county')) {
                $table->string('county', 128)->default('')->after('town');
            }
            if (!Schema::hasColumn('customers', 'postcode')) {
                $table->string('postcode', 12)->default('')->after('county');
            }
            if (!Schema::hasColumn('customers', 'kashflow_id')) {
                $table->unsignedBigInteger('kashflow_id')->nullable()->after('postcode');
            }
            if (!Schema::hasColumn('customers', 'xero_id')) {
                $table->string('xero_id', 255)->nullable()->after('kashflow_id');
            }
            if (!Schema::hasColumn('customers', 'blind_notes')) {
                $table->text('blind_notes')->nullable()->after('xero_id');
            }
            if (!Schema::hasColumn('customers', 'enable_feedback')) {
                $table->tinyInteger('enable_feedback')->default(1)->after('blind_notes');
            }
            if (!Schema::hasColumn('customers', 'flagged')) {
                $table->tinyInteger('flagged')->default(0)->after('enable_feedback');
            }
            if (!Schema::hasColumn('customers', 'sugarcrm_id')) {
                $table->string('sugarcrm_id', 255)->nullable()->after('flagged');
            }
            if (!Schema::hasColumn('customers', 'deleted_at')) {
                $table->timestamp('deleted_at')->nullable()->after('updated_at');
            }
        });
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'customers'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('customers_name_index', $indexNames)) {
            Schema::table('customers', function (Blueprint $table) {
                $table->index(['first_name','last_name'], 'customers_name_index');
            });
        }
        if (!in_array('customers_email_index', $indexNames)) {
            Schema::table('customers', function (Blueprint $table) {
                $table->index('email', 'customers_email_index');
            });
        }
        if (!in_array('customers_phone_index', $indexNames)) {
            Schema::table('customers', function (Blueprint $table) {
                $table->index('phone', 'customers_phone_index');
            });
        }
        if (!in_array('customers_mobile_index', $indexNames)) {
            Schema::table('customers', function (Blueprint $table) {
                $table->index('mobile', 'customers_mobile_index');
            });
        }
        if (!in_array('customers_deleted_at_index', $indexNames)) {
            Schema::table('customers', function (Blueprint $table) {
                $table->index('deleted_at', 'customers_deleted_at_index');
            });
        }

        // SITES TABLE
        Schema::table('sites', function (Blueprint $table) {
            if (!Schema::hasColumn('sites', 'address2')) {
                $table->string('address2', 128)->nullable()->after('address');
            }
        });
        $indexes = DB::select("SELECT INDEX_NAME FROM information_schema.statistics WHERE table_schema = ? AND table_name = 'sites'", [$connection]);
        $indexNames = collect($indexes)->pluck('INDEX_NAME')->toArray();
        if (!in_array('sites_client_id_foreign', $indexNames)) {
            Schema::table('sites', function (Blueprint $table) {
                $table->index('client_id', 'sites_client_id_foreign');
            });
        }
        if (!in_array('sites_primary_phone_index', $indexNames)) {
            Schema::table('sites', function (Blueprint $table) {
                $table->index('primary_phone', 'sites_primary_phone_index');
            });
        }

        // SITE_USERS TABLE
        Schema::table('site_users', function (Blueprint $table) {
            if (!Schema::hasColumn('site_users', 'email')) {
                $table->string('email', 64)->default('')->after('last_name');
            }
            if (!Schema::hasColumn('site_users', 'phone')) {
                $table->string('phone', 15)->default('')->after('email');
            }
            if (!Schema::hasColumn('site_users', 'mobile')) {
                $table->string('mobile', 15)->default('')->after('phone');
            }
            if (!Schema::hasColumn('site_users', 'position')) {
                $table->string('position', 64)->after('mobile');
            }
            if (!Schema::hasColumn('site_users', 'authority')) {
                $table->tinyInteger('authority')->default(0)->after('position');
            }
        });

        // Ensure 'deleted_at' column exists in 'projects' table for soft deletes
        Schema::table('projects', function (Blueprint $table) use ($connection) {
            if (!Schema::hasColumn('projects', 'deleted_at')) {
                $table->timestamp('deleted_at')->nullable()->after('updated_at');
            }
        });

        // TASKS TABLE
        Schema::table('tasks', function (Blueprint $table) {
            if (!Schema::hasColumn('tasks', 'return_id')) {
                $table->unsignedBigInteger('return_id')->nullable()->after('id');
            }
            if (!Schema::hasColumn('tasks', 'delivered')) {
                $table->tinyInteger('delivered')->default(0)->after('needs_delivery');
            }
            if (!Schema::hasColumn('tasks', 'partstmp_price')) {
                $table->decimal('partstmp_price', 10, 2)->nullable()->after('labour');
            }
            if (!Schema::hasColumn('tasks', 'booking_fee_id')) {
                $table->unsignedBigInteger('booking_fee_id')->nullable()->after('return_id');
            }
            if (!Schema::hasColumn('tasks', 'subtype_id')) {
                $table->unsignedBigInteger('subtype_id')->nullable()->after('severity_id');
            }
            if (!Schema::hasColumn('tasks', 'order_task_id')) {
                $table->unsignedBigInteger('order_task_id')->nullable()->after('project_id');
            }
            if (!Schema::hasColumn('tasks', 'delivered_by')) {
                $table->unsignedBigInteger('delivered_by')->nullable()->after('delivered');
            }
            if (!Schema::hasColumn('tasks', 'pin')) {
                $table->string('pin', 32)->nullable()->after('delivered_by');
            }
            if (!Schema::hasColumn('tasks', 'paid')) {
                $table->tinyInteger('paid')->default(0)->after('pin');
            }
            if (!Schema::hasColumn('tasks', 'paid_at')) {
                $table->timestamp('paid_at')->nullable()->after('paid');
            }
            if (!Schema::hasColumn('tasks', 'invoiced')) {
                $table->tinyInteger('invoiced')->default(0)->after('paid_at');
            }
            if (!Schema::hasColumn('tasks', 'invoiced_at')) {
                $table->timestamp('invoiced_at')->nullable()->after('invoiced');
            }
            if (!Schema::hasColumn('tasks', 'invoice_number')) {
                $table->unsignedBigInteger('invoice_number')->nullable()->after('invoiced_at');
            }
            if (!Schema::hasColumn('tasks', 'standard_price_id')) {
                $table->unsignedBigInteger('standard_price_id')->nullable()->after('invoice_number');
            }
            if (!Schema::hasColumn('tasks', 'auto_booked')) {
                $table->tinyInteger('auto_booked')->default(0)->after('standard_price_id');
            }
            if (!Schema::hasColumn('tasks', 'exchange_id')) {
                $table->string('exchange_id', 255)->nullable()->after('auto_booked');
            }
            if (!Schema::hasColumn('tasks', 'no_price_reason')) {
                $table->text('no_price_reason')->nullable()->after('exchange_id');
            }
            if (!Schema::hasColumn('tasks', 'nopassword_reason')) {
                $table->string('nopassword_reason', 128)->nullable()->after('no_price_reason');
            }
            if (!Schema::hasColumn('tasks', 'shelf_type')) {
                $table->integer('shelf_type')->nullable()->after('nopassword_reason');
            }
            if (!Schema::hasColumn('tasks', 'shelf')) {
                $table->string('shelf', 32)->nullable()->after('shelf_type');
            }
            if (!Schema::hasColumn('tasks', 'followup_id')) {
                $table->unsignedBigInteger('followup_id')->nullable()->after('shelf');
            }
            if (!Schema::hasColumn('tasks', 'passed_qa')) {
                $table->tinyInteger('passed_qa')->nullable()->after('followup_id');
            }
            if (!Schema::hasColumn('tasks', 'satisfied_client')) {
                $table->tinyInteger('satisfied_client')->nullable()->after('passed_qa');
            }
            if (!Schema::hasColumn('tasks', 'formatedAttendedTime')) {
                $table->string('formatedAttendedTime', 32)->nullable()->after('satisfied_client');
            }
            if (!Schema::hasColumn('tasks', 'formatedUnattendedTime')) {
                $table->string('formatedUnattendedTime', 32)->nullable()->after('formatedAttendedTime');
            }
            if (!Schema::hasColumn('tasks', 'recurring')) {
                $table->tinyInteger('recurring')->default(0)->after('formatedUnattendedTime');
            }
        });

        // PROJECTS TABLE
        Schema::table('projects', function (Blueprint $table) {
            if (!Schema::hasColumn('projects', 'status_id')) {
                $table->unsignedBigInteger('status_id')->nullable()->after('name');
            }
            if (!Schema::hasColumn('projects', 'budget')) {
                $table->decimal('budget', 12, 2)->nullable()->after('status_id');
            }
            if (!Schema::hasColumn('projects', 'expenses')) {
                $table->decimal('expenses', 12, 2)->nullable()->after('budget');
            }
            if (!Schema::hasColumn('projects', 'estimated_duration')) {
                $table->integer('estimated_duration')->nullable()->after('expenses');
            }
            if (!Schema::hasColumn('projects', 'single_invoice')) {
                $table->tinyInteger('single_invoice')->default(0)->after('estimated_duration');
            }
            if (!Schema::hasColumn('projects', 'site_id')) {
                $table->unsignedBigInteger('site_id')->nullable()->after('single_invoice');
            }
            if (!Schema::hasColumn('projects', 'site_user_id')) {
                $table->unsignedBigInteger('site_user_id')->nullable()->after('site_id');
            }
            if (!Schema::hasColumn('projects', 'planning')) {
                $table->tinyInteger('planning')->default(0)->after('site_user_id');
            }
            if (!Schema::hasColumn('projects', 'invoiced')) {
                $table->tinyInteger('invoiced')->default(0)->after('planning');
            }
            if (!Schema::hasColumn('projects', 'paid')) {
                $table->tinyInteger('paid')->default(0)->after('invoiced');
            }
            if (!Schema::hasColumn('projects', 'completed_at')) {
                $table->timestamp('completed_at')->nullable()->after('paid');
            }
            if (!Schema::hasColumn('projects', 'created_by')) {
                $table->unsignedBigInteger('created_by')->nullable()->after('completed_at');
            }
        });

        // ACTIVITY_LOGS TABLE
        if (!Schema::hasTable('activity_logs')) {
            Schema::create('activity_logs', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('action')->nullable();
                $table->string('object_type')->nullable();
                $table->unsignedBigInteger('object_id')->nullable();
                $table->text('description')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('activity_logs', function (Blueprint $table) {
                if (!Schema::hasColumn('activity_logs', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('activity_logs', 'action')) {
                    $table->string('action')->nullable();
                }
                if (!Schema::hasColumn('activity_logs', 'object_type')) {
                    $table->string('object_type')->nullable();
                }
                if (!Schema::hasColumn('activity_logs', 'object_id')) {
                    $table->unsignedBigInteger('object_id')->nullable();
                }
                if (!Schema::hasColumn('activity_logs', 'description')) {
                    $table->text('description')->nullable();
                }
                if (!Schema::hasColumn('activity_logs', 'created_at') || !Schema::hasColumn('activity_logs', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // ASSIGNED_CHANGES TABLE
        if (!Schema::hasTable('assigned_changes')) {
            Schema::create('assigned_changes', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('related_id')->nullable();
                $table->string('related_type')->nullable();
                $table->unsignedBigInteger('old_user')->nullable();
                $table->unsignedBigInteger('new_user')->nullable();
                $table->unsignedBigInteger('changed_by')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('assigned_changes', function (Blueprint $table) {
                if (!Schema::hasColumn('assigned_changes', 'related_id')) {
                    $table->unsignedBigInteger('related_id')->nullable();
                }
                if (!Schema::hasColumn('assigned_changes', 'related_type')) {
                    $table->string('related_type')->nullable();
                }
                if (!Schema::hasColumn('assigned_changes', 'old_user')) {
                    $table->unsignedBigInteger('old_user')->nullable();
                }
                if (!Schema::hasColumn('assigned_changes', 'new_user')) {
                    $table->unsignedBigInteger('new_user')->nullable();
                }
                if (!Schema::hasColumn('assigned_changes', 'changed_by')) {
                    $table->unsignedBigInteger('changed_by')->nullable();
                }
                if (!Schema::hasColumn('assigned_changes', 'created_at') || !Schema::hasColumn('assigned_changes', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // CONTRACTS_TASKS TABLE
        if (!Schema::hasTable('contracts_tasks')) {
            Schema::create('contracts_tasks', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('customer_id')->nullable();
                $table->string('customer_type')->nullable();
                $table->boolean('on-site')->default(false);
                $table->boolean('emergency')->default(false);
                $table->boolean('recurring')->default(false);
                $table->dateTime('start')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('contracts_tasks', function (Blueprint $table) {
                if (!Schema::hasColumn('contracts_tasks', 'customer_id')) {
                    $table->unsignedBigInteger('customer_id')->nullable();
                }
                if (!Schema::hasColumn('contracts_tasks', 'customer_type')) {
                    $table->string('customer_type')->nullable();
                }
                if (!Schema::hasColumn('contracts_tasks', 'on-site')) {
                    $table->boolean('on-site')->default(false);
                }
                if (!Schema::hasColumn('contracts_tasks', 'emergency')) {
                    $table->boolean('emergency')->default(false);
                }
                if (!Schema::hasColumn('contracts_tasks', 'recurring')) {
                    $table->boolean('recurring')->default(false);
                }
                if (!Schema::hasColumn('contracts_tasks', 'start')) {
                    $table->dateTime('start')->nullable();
                }
                if (!Schema::hasColumn('contracts_tasks', 'created_at') || !Schema::hasColumn('contracts_tasks', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // FILES TABLE
        if (!Schema::hasTable('files')) {
            Schema::create('files', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('filename')->nullable();
                $table->string('original_filename')->nullable();
                $table->string('object_type')->nullable();
                $table->unsignedBigInteger('object_id')->nullable();
                $table->unsignedBigInteger('user_id')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('files', function (Blueprint $table) {
                if (!Schema::hasColumn('files', 'filename')) {
                    $table->string('filename')->nullable();
                }
                if (!Schema::hasColumn('files', 'original_filename')) {
                    $table->string('original_filename')->nullable();
                }
                if (!Schema::hasColumn('files', 'object_type')) {
                    $table->string('object_type')->nullable();
                }
                if (!Schema::hasColumn('files', 'object_id')) {
                    $table->unsignedBigInteger('object_id')->nullable();
                }
                if (!Schema::hasColumn('files', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('files', 'created_at') || !Schema::hasColumn('files', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // FOLLOWS TABLE
        if (!Schema::hasTable('follows')) {
            Schema::create('follows', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id')->nullable();
                $table->unsignedBigInteger('related_id')->nullable();
                $table->string('related_type')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('follows', function (Blueprint $table) {
                if (!Schema::hasColumn('follows', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('follows', 'related_id')) {
                    $table->unsignedBigInteger('related_id')->nullable();
                }
                if (!Schema::hasColumn('follows', 'related_type')) {
                    $table->string('related_type')->nullable();
                }
                if (!Schema::hasColumn('follows', 'created_at') || !Schema::hasColumn('follows', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // PROFILE_PHOTOS TABLE
        if (!Schema::hasTable('profile_photos')) {
            Schema::create('profile_photos', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->nullable();
                $table->integer('size')->nullable();
                $table->string('filename')->nullable();
            });
        } else {
            Schema::table('profile_photos', function (Blueprint $table) {
                if (!Schema::hasColumn('profile_photos', 'name')) {
                    $table->string('name')->nullable();
                }
                if (!Schema::hasColumn('profile_photos', 'size')) {
                    $table->integer('size')->nullable();
                }
                if (!Schema::hasColumn('profile_photos', 'filename')) {
                    $table->string('filename')->nullable();
                }
            });
        }

        // SLA_LOGS TABLE
        if (!Schema::hasTable('sla_logs')) {
            Schema::create('sla_logs', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('task_id')->nullable();
                $table->string('type')->nullable();
                $table->boolean('missed')->default(false);
                $table->integer('duration')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('sla_logs', function (Blueprint $table) {
                if (!Schema::hasColumn('sla_logs', 'task_id')) {
                    $table->unsignedBigInteger('task_id')->nullable();
                }
                if (!Schema::hasColumn('sla_logs', 'type')) {
                    $table->string('type')->nullable();
                }
                if (!Schema::hasColumn('sla_logs', 'missed')) {
                    $table->boolean('missed')->default(false);
                }
                if (!Schema::hasColumn('sla_logs', 'duration')) {
                    $table->integer('duration')->nullable();
                }
                if (!Schema::hasColumn('sla_logs', 'created_at') || !Schema::hasColumn('sla_logs', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // STATUSES TABLE
        if (!Schema::hasTable('statuses')) {
            Schema::create('statuses', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->nullable();
                $table->boolean('completed')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('statuses', function (Blueprint $table) {
                if (!Schema::hasColumn('statuses', 'completed')) {
                    $table->boolean('completed')->default(false);
                }
            });
        }

        // VALIDATION_MODELS TABLE
        if (!Schema::hasTable('validation_models')) {
            Schema::create('validation_models', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->timestamps();
            });
        } else {
            Schema::table('validation_models', function (Blueprint $table) {
                if (!Schema::hasColumn('validation_models', 'created_at') || !Schema::hasColumn('validation_models', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // EMAIL_SETTINGS TABLE
        Schema::table('email_settings', function (Blueprint $table) {
            if (!Schema::hasColumn('email_settings', 'name')) {
                $table->string('name')->nullable();
            }
            if (!Schema::hasColumn('email_settings', 'email')) {
                $table->string('email')->nullable();
            }
            if (!Schema::hasColumn('email_settings', 'booking_type')) {
                $table->string('booking_type')->nullable();
            }
            if (!Schema::hasColumn('email_settings', 'server')) {
                $table->string('server')->nullable();
            }
            if (!Schema::hasColumn('email_settings', 'protocol')) {
                $table->string('protocol')->nullable();
            }
        });

        // CALLS TABLE
        if (!Schema::hasTable('calls')) {
            Schema::create('calls', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('uniqueid')->nullable();
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('extension')->nullable();
                $table->unsignedBigInteger('client_id')->nullable();
                $table->string('client_type')->nullable();
                $table->string('number')->nullable();
                $table->string('call_type')->nullable();
                $table->string('state')->nullable();
                $table->dateTime('dialed_time')->nullable();
                $table->dateTime('answered_time')->nullable();
                $table->text('message')->nullable();
                $table->boolean('tab_opened')->default(false);
                $table->unsignedBigInteger('task_id')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('calls', function (Blueprint $table) {
                if (!Schema::hasColumn('calls', 'uniqueid')) {
                    $table->string('uniqueid')->nullable();
                }
                if (!Schema::hasColumn('calls', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('calls', 'extension')) {
                    $table->string('extension')->nullable();
                }
                if (!Schema::hasColumn('calls', 'client_id')) {
                    $table->unsignedBigInteger('client_id')->nullable();
                }
                if (!Schema::hasColumn('calls', 'client_type')) {
                    $table->string('client_type')->nullable();
                }
                if (!Schema::hasColumn('calls', 'number')) {
                    $table->string('number')->nullable();
                }
                if (!Schema::hasColumn('calls', 'call_type')) {
                    $table->string('call_type')->nullable();
                }
                if (!Schema::hasColumn('calls', 'state')) {
                    $table->string('state')->nullable();
                }
                if (!Schema::hasColumn('calls', 'dialed_time')) {
                    $table->dateTime('dialed_time')->nullable();
                }
                if (!Schema::hasColumn('calls', 'answered_time')) {
                    $table->dateTime('answered_time')->nullable();
                }
                if (!Schema::hasColumn('calls', 'message')) {
                    $table->text('message')->nullable();
                }
                if (!Schema::hasColumn('calls', 'tab_opened')) {
                    $table->boolean('tab_opened')->default(false);
                }
                if (!Schema::hasColumn('calls', 'task_id')) {
                    $table->unsignedBigInteger('task_id')->nullable();
                }
                if (!Schema::hasColumn('calls', 'created_at') || !Schema::hasColumn('calls', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // COMMENTS TABLE
        if (!Schema::hasTable('comments')) {
            Schema::create('comments', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->boolean('read')->default(false);
                $table->string('emailed_to')->nullable();
                $table->string('from_name')->nullable();
                $table->string('from_address')->nullable();
                $table->boolean('public')->default(false);
                $table->boolean('customer_reply')->default(false);
                $table->boolean('auto_booked')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('comments', function (Blueprint $table) {
                if (!Schema::hasColumn('comments', 'read')) {
                    $table->boolean('read')->default(false);
                }
                if (!Schema::hasColumn('comments', 'emailed_to')) {
                    $table->string('emailed_to')->nullable();
                }
                if (!Schema::hasColumn('comments', 'from_name')) {
                    $table->string('from_name')->nullable();
                }
                if (!Schema::hasColumn('comments', 'from_address')) {
                    $table->string('from_address')->nullable();
                }
                if (!Schema::hasColumn('comments', 'public')) {
                    $table->boolean('public')->default(false);
                }
                if (!Schema::hasColumn('comments', 'customer_reply')) {
                    $table->boolean('customer_reply')->default(false);
                }
                if (!Schema::hasColumn('comments', 'auto_booked')) {
                    $table->boolean('auto_booked')->default(false);
                }
            });
        }

        // MANUFACTURERS TABLE
        if (!Schema::hasTable('manufacturers')) {
            Schema::create('manufacturers', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('manufacturers', function (Blueprint $table) {
                if (!Schema::hasColumn('manufacturers', 'name')) {
                    $table->string('name')->nullable();
                }
                if (!Schema::hasColumn('manufacturers', 'created_at') || !Schema::hasColumn('manufacturers', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // MESSAGES TABLE
        if (!Schema::hasTable('messages')) {
            Schema::create('messages', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('site_user_id')->nullable();
                $table->string('contact_number')->nullable();
            });
        } else {
            Schema::table('messages', function (Blueprint $table) {
                if (!Schema::hasColumn('messages', 'site_user_id')) {
                    $table->unsignedBigInteger('site_user_id')->nullable();
                }
                if (!Schema::hasColumn('messages', 'contact_number')) {
                    $table->string('contact_number')->nullable();
                }
            });
        }

        // MODEL_NUMBERS TABLE
        if (!Schema::hasTable('model_numbers')) {
            Schema::create('model_numbers', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('manufacturer_id')->nullable();
                $table->string('model_number')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('model_numbers', function (Blueprint $table) {
                if (!Schema::hasColumn('model_numbers', 'manufacturer_id')) {
                    $table->unsignedBigInteger('manufacturer_id')->nullable();
                }
                if (!Schema::hasColumn('model_numbers', 'model_number')) {
                    $table->string('model_number')->nullable();
                }
                if (!Schema::hasColumn('model_numbers', 'created_at') || !Schema::hasColumn('model_numbers', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // PARTS TABLE
        if (!Schema::hasTable('parts')) {
            Schema::create('parts', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->decimal('price', 10, 2)->nullable();
                $table->decimal('vat', 5, 2)->nullable();
            });
        } else {
            Schema::table('parts', function (Blueprint $table) {
                if (!Schema::hasColumn('parts', 'price')) {
                    $table->decimal('price', 10, 2)->nullable();
                }
                if (!Schema::hasColumn('parts', 'vat')) {
                    $table->decimal('vat', 5, 2)->nullable();
                }
            });
        }

        // TASK_FEEDBACK TABLE
        if (!Schema::hasTable('task_feedback')) {
            Schema::create('task_feedback', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('task_id')->nullable();
                $table->string('code')->nullable();
                $table->text('feedback')->nullable();
                $table->boolean('emailed')->default(false);
                $table->dateTime('emailed_at')->nullable();
                $table->boolean('reminder_sent')->default(false);
            });
        } else {
            Schema::table('task_feedback', function (Blueprint $table) {
                if (!Schema::hasColumn('task_feedback', 'task_id')) {
                    $table->unsignedBigInteger('task_id')->nullable();
                }
                if (!Schema::hasColumn('task_feedback', 'code')) {
                    $table->string('code')->nullable();
                }
                if (!Schema::hasColumn('task_feedback', 'feedback')) {
                    $table->text('feedback')->nullable();
                }
                if (!Schema::hasColumn('task_feedback', 'emailed')) {
                    $table->boolean('emailed')->default(false);
                }
                if (!Schema::hasColumn('task_feedback', 'emailed_at')) {
                    $table->dateTime('emailed_at')->nullable();
                }
                if (!Schema::hasColumn('task_feedback', 'reminder_sent')) {
                    $table->boolean('reminder_sent')->default(false);
                }
            });
        }

        // TEMPLATE_ITEMS TABLE
        if (!Schema::hasTable('template_items')) {
            Schema::create('template_items', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('template_id')->nullable();
                $table->string('description')->nullable();
                $table->string('value')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('template_items', function (Blueprint $table) {
                if (!Schema::hasColumn('template_items', 'template_id')) {
                    $table->unsignedBigInteger('template_id')->nullable();
                }
                if (!Schema::hasColumn('template_items', 'description')) {
                    $table->string('description')->nullable();
                }
                if (!Schema::hasColumn('template_items', 'value')) {
                    $table->string('value')->nullable();
                }
                if (!Schema::hasColumn('template_items', 'created_at') || !Schema::hasColumn('template_items', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // CHAT_CHANNELS TABLE
        if (!Schema::hasTable('chat_channels')) {
            Schema::create('chat_channels', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('tag')->nullable();
                $table->boolean('public')->default(false);
                $table->unsignedBigInteger('related_id')->nullable();
                $table->string('related_type')->nullable();
                $table->boolean('closed')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('chat_channels', function (Blueprint $table) {
                if (!Schema::hasColumn('chat_channels', 'tag')) {
                    $table->string('tag')->nullable();
                }
                if (!Schema::hasColumn('chat_channels', 'public')) {
                    $table->boolean('public')->default(false);
                }
                if (!Schema::hasColumn('chat_channels', 'related_id')) {
                    $table->unsignedBigInteger('related_id')->nullable();
                }
                if (!Schema::hasColumn('chat_channels', 'related_type')) {
                    $table->string('related_type')->nullable();
                }
                if (!Schema::hasColumn('chat_channels', 'closed')) {
                    $table->boolean('closed')->default(false);
                }
                if (!Schema::hasColumn('chat_channels', 'created_at') || !Schema::hasColumn('chat_channels', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // CHAT_MESSAGES TABLE
        if (!Schema::hasTable('chat_messages')) {
            Schema::create('chat_messages', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('thread_id')->nullable();
                $table->unsignedBigInteger('from_id')->nullable();
                $table->text('message')->nullable();
                $table->string('to')->nullable();
                $table->string('channel')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('chat_messages', function (Blueprint $table) {
                if (!Schema::hasColumn('chat_messages', 'thread_id')) {
                    $table->unsignedBigInteger('thread_id')->nullable();
                }
                if (!Schema::hasColumn('chat_messages', 'from_id')) {
                    $table->unsignedBigInteger('from_id')->nullable();
                }
                if (!Schema::hasColumn('chat_messages', 'message')) {
                    $table->text('message')->nullable();
                }
                if (!Schema::hasColumn('chat_messages', 'to')) {
                    $table->string('to')->nullable();
                }
                if (!Schema::hasColumn('chat_messages', 'channel')) {
                    $table->string('channel')->nullable();
                }
                if (!Schema::hasColumn('chat_messages', 'created_at') || !Schema::hasColumn('chat_messages', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // LICENSES TABLE
        if (!Schema::hasTable('licenses')) {
            Schema::create('licenses', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('client_id')->nullable();
                $table->string('client_type')->nullable();
                $table->string('product')->nullable();
                $table->string('key')->nullable();
                $table->date('expiry_date')->nullable();
                $table->unsignedBigInteger('created_by')->nullable();
                $table->unsignedBigInteger('updated_by')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('licenses', function (Blueprint $table) {
                if (!Schema::hasColumn('licenses', 'client_id')) {
                    $table->unsignedBigInteger('client_id')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'client_type')) {
                    $table->string('client_type')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'product')) {
                    $table->string('product')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'key')) {
                    $table->string('key')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'expiry_date')) {
                    $table->date('expiry_date')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'created_by')) {
                    $table->unsignedBigInteger('created_by')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'updated_by')) {
                    $table->unsignedBigInteger('updated_by')->nullable();
                }
                if (!Schema::hasColumn('licenses', 'created_at') || !Schema::hasColumn('licenses', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // POINTS_TRANSACTIONS TABLE
        if (!Schema::hasTable('points_transactions')) {
            Schema::create('points_transactions', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('identifier')->nullable();
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('action')->nullable();
                $table->decimal('amount', 10, 2)->nullable();
                $table->unsignedBigInteger('task_id')->nullable();
                $table->text('description')->nullable();
                $table->unsignedBigInteger('created_by')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('points_transactions', function (Blueprint $table) {
                if (!Schema::hasColumn('points_transactions', 'identifier')) {
                    $table->string('identifier')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'action')) {
                    $table->string('action')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'amount')) {
                    $table->decimal('amount', 10, 2)->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'task_id')) {
                    $table->unsignedBigInteger('task_id')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'description')) {
                    $table->text('description')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'created_by')) {
                    $table->unsignedBigInteger('created_by')->nullable();
                }
                if (!Schema::hasColumn('points_transactions', 'created_at') || !Schema::hasColumn('points_transactions', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // HR_HOLIDAYS TABLE
        if (!Schema::hasTable('hr_holidays')) {
            Schema::create('hr_holidays', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('description')->nullable();
                $table->date('start_date')->nullable();
                $table->date('end_date')->nullable();
                $table->boolean('paid')->default(false);
                $table->string('status')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('hr_holidays', function (Blueprint $table) {
                if (!Schema::hasColumn('hr_holidays', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('hr_holidays', 'description')) {
                    $table->string('description')->nullable();
                }
                if (!Schema::hasColumn('hr_holidays', 'start_date')) {
                    $table->date('start_date')->nullable();
                }
                if (!Schema::hasColumn('hr_holidays', 'end_date')) {
                    $table->date('end_date')->nullable();
                }
                if (!Schema::hasColumn('hr_holidays', 'paid')) {
                    $table->boolean('paid')->default(false);
                }
                if (!Schema::hasColumn('hr_holidays', 'status')) {
                    $table->string('status')->nullable();
                }
                if (!Schema::hasColumn('hr_holidays', 'created_at') || !Schema::hasColumn('hr_holidays', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // HR_PROCESSED_TIME_LOGS TABLE
        if (!Schema::hasTable('hr_processed_time_logs')) {
            Schema::create('hr_processed_time_logs', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('department_id')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('hr_processed_time_logs', function (Blueprint $table) {
                if (!Schema::hasColumn('hr_processed_time_logs', 'department_id')) {
                    $table->unsignedBigInteger('department_id')->nullable();
                }
            });
        }

        // HR_TIME_LOG_CHANGE_REQUESTS TABLE
        if (!Schema::hasTable('hr_time_log_change_requests')) {
            Schema::create('hr_time_log_change_requests', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('time_log_id')->nullable();
                $table->dateTime('time')->nullable();
                $table->boolean('completed')->default(false);
                $table->boolean('declined')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('hr_time_log_change_requests', function (Blueprint $table) {
                if (!Schema::hasColumn('hr_time_log_change_requests', 'time_log_id')) {
                    $table->unsignedBigInteger('time_log_id')->nullable();
                }
                if (!Schema::hasColumn('hr_time_log_change_requests', 'time')) {
                    $table->dateTime('time')->nullable();
                }
                if (!Schema::hasColumn('hr_time_log_change_requests', 'completed')) {
                    $table->boolean('completed')->default(false);
                }
                if (!Schema::hasColumn('hr_time_log_change_requests', 'declined')) {
                    $table->boolean('declined')->default(false);
                }
                if (!Schema::hasColumn('hr_time_log_change_requests', 'created_at') || !Schema::hasColumn('hr_time_log_change_requests', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // TIMESHEETS TABLE
        if (!Schema::hasTable('timesheets')) {
            Schema::create('timesheets', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->timestamps();
            });
        } else {
            Schema::table('timesheets', function (Blueprint $table) {
                if (!Schema::hasColumn('timesheets', 'created_at') || !Schema::hasColumn('timesheets', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // HR_USER_DETAILS TABLE
        if (!Schema::hasTable('hr_user_details')) {
            Schema::create('hr_user_details', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('type')->nullable();
                $table->dateTime('time')->nullable();
            });
        } else {
            Schema::table('hr_user_details', function (Blueprint $table) {
                if (!Schema::hasColumn('hr_user_details', 'type')) {
                    $table->string('type')->nullable();
                }
                if (!Schema::hasColumn('hr_user_details', 'time')) {
                    $table->dateTime('time')->nullable();
                }
            });
        }

        // INVOICE_EMAILS TABLE
        if (!Schema::hasTable('invoice_emails')) {
            Schema::create('invoice_emails', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('invoice_id')->nullable();
                $table->string('sent_to')->nullable();
                $table->string('subject')->nullable();
                $table->text('message')->nullable();
                $table->unsignedBigInteger('created_by')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('invoice_emails', function (Blueprint $table) {
                if (!Schema::hasColumn('invoice_emails', 'invoice_id')) {
                    $table->unsignedBigInteger('invoice_id')->nullable();
                }
                if (!Schema::hasColumn('invoice_emails', 'sent_to')) {
                    $table->string('sent_to')->nullable();
                }
                if (!Schema::hasColumn('invoice_emails', 'subject')) {
                    $table->string('subject')->nullable();
                }
                if (!Schema::hasColumn('invoice_emails', 'message')) {
                    $table->text('message')->nullable();
                }
                if (!Schema::hasColumn('invoice_emails', 'created_by')) {
                    $table->unsignedBigInteger('created_by')->nullable();
                }
                if (!Schema::hasColumn('invoice_emails', 'created_at') || !Schema::hasColumn('invoice_emails', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // INVOICE_TRANSACTIONS TABLE
        if (!Schema::hasTable('invoice_transactions')) {
            Schema::create('invoice_transactions', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('kashflow_id')->nullable();
                $table->string('type')->nullable();
                $table->date('payment_date')->nullable();
                $table->text('notes')->nullable();
            });
        } else {
            Schema::table('invoice_transactions', function (Blueprint $table) {
                if (!Schema::hasColumn('invoice_transactions', 'kashflow_id')) {
                    $table->unsignedBigInteger('kashflow_id')->nullable();
                }
                if (!Schema::hasColumn('invoice_transactions', 'type')) {
                    $table->string('type')->nullable();
                }
                if (!Schema::hasColumn('invoice_transactions', 'payment_date')) {
                    $table->date('payment_date')->nullable();
                }
                if (!Schema::hasColumn('invoice_transactions', 'notes')) {
                    $table->text('notes')->nullable();
                }
            });
        }

        // NOTIFICATIONS TABLE
        if (!Schema::hasTable('notifications')) {
            Schema::create('notifications', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('related_type')->nullable();
                $table->unsignedBigInteger('related_id')->nullable();
                $table->text('message')->nullable();
                $table->boolean('read')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('notifications', function (Blueprint $table) {
                if (!Schema::hasColumn('notifications', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('notifications', 'related_type')) {
                    $table->string('related_type')->nullable();
                }
                if (!Schema::hasColumn('notifications', 'related_id')) {
                    $table->unsignedBigInteger('related_id')->nullable();
                }
                if (!Schema::hasColumn('notifications', 'message')) {
                    $table->text('message')->nullable();
                }
                if (!Schema::hasColumn('notifications', 'read')) {
                    $table->boolean('read')->default(false);
                }
                if (!Schema::hasColumn('notifications', 'created_at') || !Schema::hasColumn('notifications', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // NOTIFICATION_SETTINGS TABLE
        if (!Schema::hasTable('notification_settings')) {
            Schema::create('notification_settings', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('user_id')->nullable();
                $table->string('notification')->nullable();
                $table->boolean('email')->default(false);
                $table->boolean('alert')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('notification_settings', function (Blueprint $table) {
                if (!Schema::hasColumn('notification_settings', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (!Schema::hasColumn('notification_settings', 'notification')) {
                    $table->string('notification')->nullable();
                }
                if (!Schema::hasColumn('notification_settings', 'email')) {
                    $table->boolean('email')->default(false);
                }
                if (!Schema::hasColumn('notification_settings', 'alert')) {
                    $table->boolean('alert')->default(false);
                }
                if (!Schema::hasColumn('notification_settings', 'created_at') || !Schema::hasColumn('notification_settings', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // PUSH_DEVICES TABLE
        if (!Schema::hasTable('push_devices')) {
            Schema::create('push_devices', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('display_id')->nullable();
            });
        } else {
            Schema::table('push_devices', function (Blueprint $table) {
                if (!Schema::hasColumn('push_devices', 'display_id')) {
                    $table->string('display_id')->nullable();
                }
            });
        }

        // STOCK_PURCHASE_ORDERS TABLE
        if (!Schema::hasTable('stock_purchase_orders')) {
            Schema::create('stock_purchase_orders', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('ordered_by')->nullable();
                $table->unsignedBigInteger('payments_id')->nullable();
                $table->string('xeroId')->nullable();
            });
        } else {
            Schema::table('stock_purchase_orders', function (Blueprint $table) {
                if (!Schema::hasColumn('stock_purchase_orders', 'ordered_by')) {
                    $table->unsignedBigInteger('ordered_by')->nullable();
                }
                if (!Schema::hasColumn('stock_purchase_orders', 'payments_id')) {
                    $table->unsignedBigInteger('payments_id')->nullable();
                }
                if (!Schema::hasColumn('stock_purchase_orders', 'xeroId')) {
                    $table->string('xeroId')->nullable();
                }
            });
        }

        // PAYMENTS TABLE
        if (!Schema::hasTable('payments')) {
            Schema::create('payments', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->timestamps();
            });
        } else {
            Schema::table('payments', function (Blueprint $table) {
                if (!Schema::hasColumn('payments', 'created_at') || !Schema::hasColumn('payments', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // STOCK TABLE
        if (!Schema::hasTable('stock')) {
            Schema::create('stock', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('status_id')->nullable();
            });
        } else {
            Schema::table('stock', function (Blueprint $table) {
                if (!Schema::hasColumn('stock', 'status_id')) {
                    $table->unsignedBigInteger('status_id')->nullable();
                }
            });
        }

        // STOCK_ITEMS TABLE
        if (!Schema::hasTable('stock_items')) {
            Schema::create('stock_items', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->decimal('retail', 10, 2)->nullable();
                $table->unsignedBigInteger('order_id')->nullable();
            });
        } else {
            Schema::table('stock_items', function (Blueprint $table) {
                if (!Schema::hasColumn('stock_items', 'retail')) {
                    $table->decimal('retail', 10, 2)->nullable();
                }
                if (!Schema::hasColumn('stock_items', 'order_id')) {
                    $table->unsignedBigInteger('order_id')->nullable();
                }
            });
        }

        // SCHEDULED_EMAILS TABLE
        if (!Schema::hasTable('scheduled_emails')) {
            Schema::create('scheduled_emails', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('event')->nullable();
                $table->string('to')->nullable();
                $table->text('settings')->nullable();
                $table->boolean('sent')->default(false);
                $table->boolean('automatic')->default(false);
                $table->boolean('failed')->default(false);
                $table->unsignedBigInteger('task_id')->nullable();
                $table->unsignedBigInteger('client_id')->nullable();
                $table->string('client_type')->nullable();
                $table->dateTime('send_on')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('scheduled_emails', function (Blueprint $table) {
                if (!Schema::hasColumn('scheduled_emails', 'event')) {
                    $table->string('event')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'to')) {
                    $table->string('to')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'settings')) {
                    $table->text('settings')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'sent')) {
                    $table->boolean('sent')->default(false);
                }
                if (!Schema::hasColumn('scheduled_emails', 'automatic')) {
                    $table->boolean('automatic')->default(false);
                }
                if (!Schema::hasColumn('scheduled_emails', 'failed')) {
                    $table->boolean('failed')->default(false);
                }
                if (!Schema::hasColumn('scheduled_emails', 'task_id')) {
                    $table->unsignedBigInteger('task_id')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'client_id')) {
                    $table->unsignedBigInteger('client_id')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'client_type')) {
                    $table->string('client_type')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'send_on')) {
                    $table->dateTime('send_on')->nullable();
                }
                if (!Schema::hasColumn('scheduled_emails', 'created_at') || !Schema::hasColumn('scheduled_emails', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // WORKFLOW_ACTIONS TABLE
        if (!Schema::hasTable('workflow_actions')) {
            Schema::create('workflow_actions', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->unsignedBigInteger('workflow_event_id')->nullable();
                $table->string('action')->nullable();
                $table->text('settings')->nullable();
                $table->string('condition')->nullable();
                $table->timestamps();
            });
        } else {
            Schema::table('workflow_actions', function (Blueprint $table) {
                if (!Schema::hasColumn('workflow_actions', 'workflow_event_id')) {
                    $table->unsignedBigInteger('workflow_event_id')->nullable();
                }
                if (!Schema::hasColumn('workflow_actions', 'action')) {
                    $table->string('action')->nullable();
                }
                if (!Schema::hasColumn('workflow_actions', 'settings')) {
                    $table->text('settings')->nullable();
                }
                if (!Schema::hasColumn('workflow_actions', 'condition')) {
                    $table->string('condition')->nullable();
                }
                if (!Schema::hasColumn('workflow_actions', 'created_at') || !Schema::hasColumn('workflow_actions', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // WORKFLOW_EVENTS TABLE
        if (!Schema::hasTable('workflow_events')) {
            Schema::create('workflow_events', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('model')->nullable();
                $table->string('event')->nullable();
                $table->text('filters')->nullable();
                $table->boolean('active')->default(false);
                $table->timestamps();
            });
        } else {
            Schema::table('workflow_events', function (Blueprint $table) {
                if (!Schema::hasColumn('workflow_events', 'model')) {
                    $table->string('model')->nullable();
                }
                if (!Schema::hasColumn('workflow_events', 'event')) {
                    $table->string('event')->nullable();
                }
                if (!Schema::hasColumn('workflow_events', 'filters')) {
                    $table->text('filters')->nullable();
                }
                if (!Schema::hasColumn('workflow_events', 'active')) {
                    $table->boolean('active')->default(false);
                }
                if (!Schema::hasColumn('workflow_events', 'created_at') || !Schema::hasColumn('workflow_events', 'updated_at')) {
                    $table->timestamps();
                }
            });
        }

        // INVOICES TABLE
        Schema::table('invoices', function (Blueprint $table) {
            if (!Schema::hasColumn('invoices', 'type')) {
                $table->string('type')->nullable()->after('id');
            }
            if (!Schema::hasColumn('invoices', 'invoice_number')) {
                $table->string('invoice_number')->nullable()->after('type');
            }
            if (!Schema::hasColumn('invoices', 'deleted_at')) {
                $table->timestamp('deleted_at')->nullable()->after('updated_at');
            }
        });
    }

    public function down()
    {
        // Not implemented for safety
    }
} 