<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

/**
 * Permit to Work + LOTO.
 *
 *   permit_types   catalog: Hot Work, Confined Space, Working at Height, LOTO, …
 *   permits        one row per issued permit — links WO to permit-type + approver
 *
 * A WO with permit_required = 1 cannot be moved out of `assigned` (i.e.
 * cannot be started) until its permit is `approved`. Enforcement lives in
 * WorkOrder::update() via a new gating check; migration adds the columns.
 */
final class CreatePermits extends AbstractMigration
{
    public function change(): void
    {
        $this->table('permit_types', ['id' => 'permit_type_id', 'signed' => false])
            ->addColumn('tenant_id',   'integer', ['signed' => false])
            ->addColumn('code',        'string',  ['limit' => 40])
            ->addColumn('name',        'string',  ['limit' => 160])
            ->addColumn('description', 'string',  ['limit' => 255, 'null' => true])
            ->addColumn('icon',        'string',  ['limit' => 60,  'null' => true])
            ->addColumn('is_active',   'boolean', ['default' => true])
            ->addColumn('created_at',  'datetime',['default' => 'CURRENT_TIMESTAMP'])
            ->addIndex(['tenant_id', 'code'], ['unique' => true])
            ->addForeignKey('tenant_id', 'tenants', 'tenant_id', ['delete' => 'CASCADE', 'update' => 'CASCADE'])
            ->create();

        $this->table('permits', ['id' => 'permit_id', 'signed' => false])
            ->addColumn('tenant_id',       'integer', ['signed' => false])
            ->addColumn('permit_type_id',  'integer', ['signed' => false])
            ->addColumn('work_order_id',   'integer', ['null' => true, 'signed' => false])
            ->addColumn('asset_id',        'integer', ['null' => true, 'signed' => false])
            ->addColumn('site_id',         'integer', ['null' => true, 'signed' => false])
            ->addColumn('code',            'string',  ['limit' => 40,  'null' => true])
            ->addColumn('title',           'string',  ['limit' => 200])
            ->addColumn('description',     'text',    ['null' => true])
            ->addColumn('status',          'string',  ['limit' => 20,  'default' => 'draft'])
            // draft | requested | approved | rejected | active | closed | expired
            ->addColumn('hazards',         'text',    ['null' => true])
            ->addColumn('controls',        'text',    ['null' => true])
            ->addColumn('ppe',             'string',  ['limit' => 255, 'null' => true])
            ->addColumn('lockout_tags',    'string',  ['limit' => 255, 'null' => true])
            ->addColumn('valid_from',      'datetime',['null' => true])
            ->addColumn('valid_to',        'datetime',['null' => true])
            ->addColumn('requested_by',    'integer', ['null' => true, 'signed' => false])
            ->addColumn('approved_by',     'integer', ['null' => true, 'signed' => false])
            ->addColumn('approved_at',     'datetime',['null' => true])
            ->addColumn('closed_by',       'integer', ['null' => true, 'signed' => false])
            ->addColumn('closed_at',       'datetime',['null' => true])
            ->addColumn('rejection_note',  'text',    ['null' => true])
            ->addColumn('created_at',      'datetime',['default' => 'CURRENT_TIMESTAMP'])
            ->addColumn('updated_at',      'datetime',['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP'])
            ->addColumn('deleted_at',      'datetime',['null' => true])
            ->addIndex(['tenant_id', 'status'])
            ->addIndex(['work_order_id'])
            ->addIndex(['tenant_id', 'valid_to'])
            ->addForeignKey('tenant_id',      'tenants',      'tenant_id',      ['delete' => 'CASCADE',  'update' => 'CASCADE'])
            ->addForeignKey('permit_type_id', 'permit_types', 'permit_type_id', ['delete' => 'RESTRICT', 'update' => 'CASCADE'])
            ->addForeignKey('work_order_id',  'work_orders',  'work_order_id',  ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->addForeignKey('asset_id',       'assets',       'asset_id',       ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->addForeignKey('site_id',        'sites',        'site_id',        ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->addForeignKey('requested_by',   'users',        'user_id',        ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->addForeignKey('approved_by',    'users',        'user_id',        ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->addForeignKey('closed_by',      'users',        'user_id',        ['delete' => 'SET_NULL', 'update' => 'CASCADE'])
            ->create();

        // Gate column on work_orders — if 1, the WO can't start without an
        // approved permit linked back via permits.work_order_id.
        $this->table('work_orders')
            ->addColumn('permit_required', 'boolean', ['default' => false, 'after' => 'status'])
            ->update();

        // Seed the four canonical plant-safety permits per tenant.
        $tenantId = (int) ($this->fetchRow(
            "SELECT tenant_id FROM tenants WHERE subdomain = 'orchid' LIMIT 1"
        )['tenant_id'] ?? 0);
        if ($tenantId > 0) {
            $starter = [
                ['HOT',   'Hot Work',             'Welding, cutting, grinding — anything that produces sparks or heat.', 'fa-fire'],
                ['CONF',  'Confined Space Entry', 'Tanks, vessels, pits — restricted egress, atmosphere risk.',          'fa-arrows-to-dot'],
                ['HGT',   'Working at Height',    'Any work above 1.8 m where a fall hazard exists.',                    'fa-arrow-up-from-ground-water'],
                ['LOTO',  'Lockout / Tagout',     'Energy isolation — electrical, hydraulic, pneumatic, stored energy.', 'fa-lock'],
                ['ELEC',  'Live Electrical Work', 'Any live-line work above LV or requiring a barrier.',                 'fa-bolt'],
                ['EXCAV', 'Excavation',           'Digging deeper than 1.2 m or where buried services exist.',           'fa-shovel'],
            ];
            foreach ($starter as $r) {
                $this->table('permit_types')->insert([
                    'tenant_id'   => $tenantId,
                    'code'        => $r[0],
                    'name'        => $r[1],
                    'description' => $r[2],
                    'icon'        => $r[3],
                ])->saveData();
            }
        }
    }
}
