<?php

declare(strict_types=1);

namespace App\Support;

use App\Business\Inventory\Enums\InventorySerialNumberStatus;
use App\Models\DberpInventorySerialNumber;
use App\Models\DberpInventorySerialNumberLog;
use App\Models\DberpProduct;
use App\Models\DberpProductSku;
use Illuminate\Support\Str;

/**
 * 序列号档案列表/详情/日志的业务展示文案。
 */
final class DberpInventorySerialNumberPresentation
{
    public static function statusLabel(?string $status): string
    {
        if ($status === null || $status === '') {
            return '—';
        }

        $label = __('dberp.options.inventory_serial_number_status')[$status] ?? null;

        return $label !== null && $label !== 'dberp.options.inventory_serial_number_status.'.$status
            ? (string) $label
            : (string) $status;
    }

    public static function statusColor(?string $status): string
    {
        return match ($status) {
            InventorySerialNumberStatus::InStock->value => 'success',
            InventorySerialNumberStatus::Locked->value => 'warning',
            InventorySerialNumberStatus::Outbound->value => 'gray',
            InventorySerialNumberStatus::ReturnedPending->value => 'info',
            InventorySerialNumberStatus::Disabled->value => 'danger',
            InventorySerialNumberStatus::Voided->value => 'danger',
            default => 'gray',
        };
    }

    public static function enabledLabel(bool $enabled): string
    {
        return self::enabledLabelFromState($enabled);
    }

    public static function enabledLabelFromState(mixed $state): string
    {
        return self::isEnabledState($state)
            ? (string) __('dberp.fields.boolean_yes')
            : (string) __('dberp.fields.boolean_no');
    }

    public static function isEnabledState(mixed $state): bool
    {
        if ($state === null || $state === '') {
            return false;
        }

        if (is_bool($state)) {
            return $state;
        }

        if (is_int($state) || is_float($state)) {
            return (int) $state === 1;
        }

        $normalized = strtolower(trim((string) $state));

        return in_array($normalized, ['1', 'true', 'yes', 'on'], true);
    }

    public static function productSkuSummary(?DberpProduct $product): string
    {
        if (! $product instanceof DberpProduct) {
            return '—';
        }

        $sku = $product->relationLoaded('defaultSku')
            ? $product->defaultSku
            : $product->defaultSku()->first();

        if ($sku instanceof DberpProductSku) {
            $parts = array_filter([
                $sku->sku_code,
                $sku->spec_text,
            ], fn (mixed $part): bool => filled($part));

            if ($parts !== []) {
                return implode(' / ', $parts);
            }
        }

        if (filled($product->spec_model)) {
            return (string) $product->spec_model;
        }

        return '—';
    }

    public static function sourceDocumentSummary(DberpInventorySerialNumber $serialNumber): string
    {
        $type = self::sourceTypeLabel((string) $serialNumber->source_document_type);
        $number = trim((string) $serialNumber->source_document_no);

        if ($type === '—' && $number === '') {
            return '—';
        }

        if ($number === '') {
            return $type;
        }

        if ($type === '—') {
            return $number;
        }

        return $type.' · '.$number;
    }

    public static function ownerSummary(DberpInventorySerialNumber $serialNumber): string
    {
        $type = trim((string) $serialNumber->current_owner_type);
        $id = $serialNumber->current_owner_id;

        if ($type === '' && $id === null) {
            return '—';
        }

        $typeLabel = self::ownerTypeLabel($type);

        if ($id === null) {
            return $typeLabel;
        }

        return $typeLabel.' #'.$id;
    }

    public static function logSourceSummary(DberpInventorySerialNumberLog $log): string
    {
        $type = self::sourceTypeLabel((string) $log->source_type);
        $number = trim((string) $log->business_number);

        if ($type === '—' && $number === '') {
            return '—';
        }

        if ($number === '') {
            return $type;
        }

        if ($type === '—') {
            return $number;
        }

        return $type.' · '.$number;
    }

    public static function logOperationSummary(DberpInventorySerialNumberLog $log): string
    {
        $snapshot = $log->context_snapshot;

        if (! is_array($snapshot) || $snapshot === []) {
            return $log->remark ? (string) $log->remark : '—';
        }

        $parts = [];

        if (filled($snapshot['serial_no'] ?? null)) {
            $parts[] = (string) __('dberp.fields.serial_no').': '.$snapshot['serial_no'];
        }

        if (filled($snapshot['current_owner_type'] ?? null) || filled($snapshot['current_owner_id'] ?? null)) {
            $parts[] = (string) __('dberp.fields.current_owner_type').': '
                .self::ownerTypeLabel((string) ($snapshot['current_owner_type'] ?? ''))
                .(filled($snapshot['current_owner_id'] ?? null) ? ' #'.$snapshot['current_owner_id'] : '');
        }

        if ($parts === [] && filled($log->remark)) {
            return (string) $log->remark;
        }

        return $parts !== [] ? implode('；', $parts) : '—';
    }

    public static function sourceTypeLabel(string $sourceType): string
    {
        if ($sourceType === '') {
            return '—';
        }

        $snake = Str::snake(class_basename($sourceType));
        $key = 'dberp.options.inventory_serial_number_source_type.'.$snake;
        $line = __($key);

        if ($line !== $key) {
            return (string) $line;
        }

        $morphKey = 'dberp.options.inventory_serial_number_source_type.'.$sourceType;
        $morphLine = __($morphKey);

        return $morphLine !== $morphKey ? (string) $morphLine : Str::headline($snake);
    }

    public static function ownerTypeLabel(string $ownerType): string
    {
        if ($ownerType === '') {
            return '—';
        }

        $snake = Str::snake(class_basename($ownerType));
        $key = 'dberp.options.inventory_serial_number_owner_type.'.$snake;
        $line = __($key);

        if ($line !== $key) {
            return (string) $line;
        }

        $directKey = 'dberp.options.inventory_serial_number_owner_type.'.$ownerType;
        $directLine = __($directKey);

        return $directLine !== $directKey ? (string) $directLine : Str::headline($snake);
    }
}
