<?php

namespace Database\Seeders;

use App\Models\Items\Item;
use App\Models\Tenants\Receiving;
use App\Models\Tenants\Stock;
use App\Models\Tenants\StockLot;
use Illuminate\Database\Seeder;

/**
 * 재고현황, 입고관리 테스트 데이터 Seeder
 *
 * Tenant 287 기준으로 Items 데이터를 기반으로 Stock, Receiving 생성
 */
class StockReceivingSeeder extends Seeder
{
    private const TENANT_ID = 287;

    private const USER_ID = 33;

    /**
     * Item.item_type → Stock.item_type 매핑
     */
    private const ITEM_TYPE_MAP = [
        'FG' => 'purchased_part',  // 완제품
        'PT' => 'bent_part',       // 부품
        'SM' => 'sub_material',    // 부자재
        'RM' => 'raw_material',    // 원자재
        'CS' => 'consumable',      // 소모품
    ];

    public function run(): void
    {
        $this->command->info('Stock & Receiving Seeder 시작 (Tenant: '.self::TENANT_ID.')');

        // Tenant 287의 품목 조회
        $items = Item::withoutGlobalScopes()
            ->where('tenant_id', self::TENANT_ID)
            ->get();

        if ($items->isEmpty()) {
            $this->command->warn('Tenant '.self::TENANT_ID.'에 품목이 없습니다.');

            return;
        }

        $this->command->info('품목 수: '.$items->count());

        // 각 품목에 대해 재고 및 입고 데이터 생성
        foreach ($items as $item) {
            $this->createStockData($item);
            $this->createReceivingData($item);
        }

        $this->command->info('Stock & Receiving Seeder 완료');
    }

    /**
     * 재고 데이터 생성
     */
    private function createStockData(Item $item): void
    {
        $stockType = self::ITEM_TYPE_MAP[$item->item_type] ?? 'raw_material';

        // 랜덤 재고 수량
        $stockQty = rand(50, 500);
        $safetyStock = rand(10, 50);
        $reservedQty = rand(0, min(20, $stockQty));
        $availableQty = $stockQty - $reservedQty;

        // 재고 상태 결정
        $status = 'normal';
        if ($stockQty <= 0) {
            $status = 'out';
        } elseif ($stockQty < $safetyStock) {
            $status = 'low';
        }

        // 재고 레코드 생성
        $stock = Stock::withoutGlobalScopes()->create([
            'tenant_id' => self::TENANT_ID,
            'item_id' => $item->id,
            'item_code' => $item->code,
            'item_name' => $item->name,
            'item_type' => $stockType,
            'specification' => $item->attributes['specification'] ?? null,
            'unit' => $item->unit,
            'stock_qty' => $stockQty,
            'safety_stock' => $safetyStock,
            'reserved_qty' => $reservedQty,
            'available_qty' => $availableQty,
            'lot_count' => rand(1, 3),
            'oldest_lot_date' => now()->subDays(rand(30, 180)),
            'location' => $this->randomLocation(),
            'status' => $status,
            'last_receipt_date' => now()->subDays(rand(1, 30)),
            'last_issue_date' => now()->subDays(rand(1, 14)),
            'created_by' => self::USER_ID,
        ]);

        // LOT 데이터 생성 (1~3개)
        $lotCount = rand(1, 3);
        $remainingQty = $stockQty;

        for ($i = 0; $i < $lotCount && $remainingQty > 0; $i++) {
            $lotQty = $i === $lotCount - 1 ? $remainingQty : rand(10, $remainingQty);
            $remainingQty -= $lotQty;

            StockLot::withoutGlobalScopes()->create([
                'tenant_id' => self::TENANT_ID,
                'stock_id' => $stock->id,
                'lot_no' => 'LOT'.date('Ymd').'-'.str_pad($i + 1, 3, '0', STR_PAD_LEFT),
                'supplier_lot' => 'SUP-'.rand(1000, 9999),
                'qty' => $lotQty,
                'reserved_qty' => 0,
                'available_qty' => $lotQty,
                'receipt_date' => now()->subDays(rand(1, 60)),
                'fifo_order' => $i + 1,
                'location' => $stock->location,
                'status' => 'available',
                'created_by' => self::USER_ID,
            ]);
        }

        $this->command->info("  - Stock 생성: {$item->code} ({$stockQty} {$item->unit})");
    }

    /**
     * 입고 데이터 생성
     */
    private function createReceivingData(Item $item): void
    {
        // 각 품목당 2~4건의 입고 데이터 생성
        $count = rand(2, 4);

        for ($i = 0; $i < $count; $i++) {
            $orderQty = rand(50, 200);
            $status = $this->randomReceivingStatus();
            $receivingQty = $status === 'completed' ? $orderQty : ($status === 'receiving_pending' ? rand(1, $orderQty) : null);

            // 고유번호 생성을 위해 uniqid 사용
            $uniqueId = substr(uniqid(), -6);
            Receiving::withoutGlobalScopes()->create([
                'tenant_id' => self::TENANT_ID,
                'receiving_number' => 'RCV-'.date('Ymd').'-'.$uniqueId,
                'order_no' => 'PO-'.date('Ymd').'-'.str_pad(rand(1, 999), 3, '0', STR_PAD_LEFT),
                'order_date' => now()->subDays(rand(10, 60)),
                'item_id' => $item->id,
                'item_code' => $item->code,
                'item_name' => $item->name,
                'specification' => $item->attributes['specification'] ?? null,
                'supplier' => $this->randomSupplier(),
                'order_qty' => $orderQty,
                'order_unit' => $item->unit,
                'due_date' => now()->addDays(rand(-5, 14)),
                'receiving_qty' => $receivingQty,
                'receiving_date' => $status === 'completed' ? now()->subDays(rand(1, 10)) : null,
                'lot_no' => $status === 'completed' ? 'LOT'.date('Ymd').'-'.str_pad(rand(1, 999), 3, '0', STR_PAD_LEFT) : null,
                'supplier_lot' => $status === 'completed' ? 'SUP-'.rand(1000, 9999) : null,
                'receiving_location' => $status === 'completed' ? $this->randomLocation() : null,
                'receiving_manager' => $status === 'completed' ? '홍킬동' : null,
                'status' => $status,
                'remark' => $this->randomRemark(),
                'created_by' => self::USER_ID,
            ]);
        }

        $this->command->info("  - Receiving 생성: {$item->code} ({$count}건)");
    }

    /**
     * 랜덤 창고 위치
     */
    private function randomLocation(): string
    {
        $locations = ['A-01-01', 'A-01-02', 'A-02-01', 'B-01-01', 'B-02-01', 'C-01-01'];

        return $locations[array_rand($locations)];
    }

    /**
     * 랜덤 공급업체
     */
    private function randomSupplier(): string
    {
        $suppliers = ['(주)대한철강', '삼성부품', 'LG전자', '현대산업', '한국소재', '동아물산'];

        return $suppliers[array_rand($suppliers)];
    }

    /**
     * 랜덤 입고 상태
     */
    private function randomReceivingStatus(): string
    {
        $statuses = ['order_completed', 'shipping', 'inspection_pending', 'receiving_pending', 'completed'];
        $weights = [15, 15, 15, 15, 40]; // completed가 더 많이

        $rand = rand(1, array_sum($weights));
        $cumulative = 0;

        foreach ($statuses as $i => $status) {
            $cumulative += $weights[$i];
            if ($rand <= $cumulative) {
                return $status;
            }
        }

        return 'completed';
    }

    /**
     * 랜덤 비고
     */
    private function randomRemark(): ?string
    {
        $remarks = [
            null,
            '긴급 발주',
            '정기 입고',
            '추가 발주',
            '품질 검사 필요',
            '납기 지연 주의',
        ];

        return $remarks[array_rand($remarks)];
    }
}
