<?php

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

return new class extends Migration {
    private const CHANNELS = ['NOpay12', 'NOpay13', 'NOwithdraw'];

    public function up()
    {
        if (Schema::hasTable('recharge_channel')) {
            $this->upsertChannel(1, 'NO快捷充值-扫码支付', 'NOpay12', 0, 10, 49999);
            $this->upsertChannel(1, 'NO快捷充值-余额支付', 'NOpay13', 0, 10, 49999);
            $this->upsertChannel(2, 'NO快捷提现', 'NOwithdraw', 0, 10, 49999);
        }

        if (Schema::hasTable('recharge_channel_group')) {
            $this->appendGroupTypes('recharge_type', ['NOpay12', 'NOpay13']);
            $this->appendGroupTypes('withdraw_type', ['NOwithdraw']);
        }
    }

    public function down()
    {
        if (Schema::hasTable('recharge_channel')) {
            DB::table('recharge_channel')->whereIn('type', self::CHANNELS)->delete();
        }

        if (Schema::hasTable('recharge_channel_group')) {
            $this->removeGroupTypes('recharge_type', ['NOpay12', 'NOpay13']);
            $this->removeGroupTypes('withdraw_type', ['NOwithdraw']);
        }
    }

    private function upsertChannel(int $dataType, string $name, string $type, float $rate, int $min, int $max): void
    {
        $row = compact('name', 'type', 'rate', 'min', 'max');
        $row['data_type'] = $dataType;

        foreach (['key' => $type, 'fixed' => '', 'status' => 1, 'sort' => 98, 'from' => 1] as $column => $value) {
            if (Schema::hasColumn('recharge_channel', $column)) {
                $row[$column] = $value;
            }
        }

        DB::table('recharge_channel')->updateOrInsert(
            ['data_type' => $dataType, 'type' => $type],
            $row
        );
    }

    private function appendGroupTypes(string $column, array $newTypes): void
    {
        if (!Schema::hasColumn('recharge_channel_group', $column)) {
            return;
        }

        DB::table('recharge_channel_group')->orderBy('id')->chunkById(100, function ($groups) use ($column, $newTypes) {
            foreach ($groups as $group) {
                $types = array_values(array_filter(explode(',', (string)$group->{$column})));
                DB::table('recharge_channel_group')->where('id', $group->id)->update([
                    $column => implode(',', array_values(array_unique(array_merge($types, $newTypes)))),
                ]);
            }
        });
    }

    private function removeGroupTypes(string $column, array $removeTypes): void
    {
        if (!Schema::hasColumn('recharge_channel_group', $column)) {
            return;
        }

        DB::table('recharge_channel_group')->orderBy('id')->chunkById(100, function ($groups) use ($column, $removeTypes) {
            foreach ($groups as $group) {
                $types = array_values(array_diff(array_filter(explode(',', (string)$group->{$column})), $removeTypes));
                DB::table('recharge_channel_group')->where('id', $group->id)->update([
                    $column => implode(',', $types),
                ]);
            }
        });
    }
};
