<?php

namespace App\Modules\Inventory\Exports;

use App\Modules\Inventory\Models\Inventory;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class StockQueryExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize, WithStyles
{
    protected array $filters;

    public function __construct(array $filters = [])
    {
        $this->filters = $filters;
    }

    public function collection()
    {
        $today = now()->toDateString();
        $expiryThreshold = now()->addDays(30)->toDateString();

        $query = Inventory::query()
            ->join('products', 'inventories.product_id', '=', 'products.id')
            ->join('warehouses', 'inventories.warehouse_id', '=', 'warehouses.id')
            ->leftJoin('categories', 'products.category_id', '=', 'categories.id')
            ->leftJoin('warehouse_product_safety_stocks as ss', function ($join) {
                $join->on('inventories.warehouse_id', '=', 'ss.warehouse_id')
                     ->on('inventories.product_id', '=', 'ss.product_id');
            })
            ->whereNull('inventories.deleted_at')
            ->select([
                'inventories.id',
                'inventories.quantity',
                'inventories.batch_number',
                'inventories.expiry_date',
                'inventories.quality_status',
                'products.code as product_code',
                'products.name as product_name',
                'categories.name as category_name',
                'warehouses.name as warehouse_name',
                'ss.safety_stock',
            ]);

        // 篩選
        if (!empty($this->filters['warehouse_id'])) {
            $query->where('inventories.warehouse_id', $this->filters['warehouse_id']);
        }
        if (!empty($this->filters['category_id'])) {
            $query->where('products.category_id', $this->filters['category_id']);
        }
        if (!empty($this->filters['search'])) {
            $search = $this->filters['search'];
            $query->where(function ($q) use ($search) {
                $q->where('products.code', 'like', "%{$search}%")
                  ->orWhere('products.name', 'like', "%{$search}%");
            });
        }
        if (!empty($this->filters['status'])) {
            switch ($this->filters['status']) {
                case 'low_stock':
                    $query->whereNotNull('ss.safety_stock')
                          ->whereRaw('inventories.quantity <= ss.safety_stock')
                          ->where('inventories.quantity', '>=', 0);
                    break;
                case 'negative':
                    $query->where('inventories.quantity', '<', 0);
                    break;
                case 'expiring':
                    $query->whereNotNull('inventories.expiry_date')
                          ->where('inventories.expiry_date', '>', $today)
                          ->where('inventories.expiry_date', '<=', $expiryThreshold);
                    break;
                case 'expired':
                    $query->whereNotNull('inventories.expiry_date')
                          ->where('inventories.expiry_date', '<=', $today);
                    break;
                case 'abnormal':
                    $query->where(function ($q) use ($today, $expiryThreshold) {
                        $q->where('inventories.quantity', '<', 0)
                          ->orWhere(function ($q2) {
                              $q2->whereNotNull('ss.safety_stock')
                                 ->whereRaw('inventories.quantity <= ss.safety_stock');
                          })
                          ->orWhere(function ($q2) use ($expiryThreshold) {
                              $q2->whereNotNull('inventories.expiry_date')
                                 ->where('inventories.expiry_date', '<=', $expiryThreshold);
                          });
                    });
                    break;
            }
        }

        return $query->orderBy('products.code', 'asc')->get();
    }

    public function headings(): array
    {
        return [
            '商品代碼',
            '商品名稱',
            '分類',
            '倉庫',
            '批號',
            '數量',
            '安全庫存',
            '到期日',
            '品質狀態',
            '狀態',
        ];
    }

    public function map($row): array
    {
        $today = now()->toDateString();
        $expiryThreshold = now()->addDays(30)->toDateString();

        $statuses = [];
        if ($row->quantity < 0) {
            $statuses[] = '負庫存';
        }
        if ($row->safety_stock !== null && $row->quantity <= $row->safety_stock && $row->quantity >= 0) {
            $statuses[] = '低庫存';
        }
        if ($row->expiry_date) {
            if ($row->expiry_date <= $today) {
                $statuses[] = '已過期';
            } elseif ($row->expiry_date <= $expiryThreshold) {
                $statuses[] = '即將過期';
            }
        }
        if (empty($statuses)) {
            $statuses[] = '正常';
        }

        $qualityLabels = [
            'normal' => '正常',
            'inspecting' => '檢驗中',
            'rejected' => '不合格',
        ];

        return [
            $row->product_code,
            $row->product_name,
            $row->category_name ?? '-',
            $row->warehouse_name,
            $row->batch_number ?? '-',
            $row->quantity,
            $row->safety_stock ?? '-',
            $row->expiry_date ?? '-',
            $qualityLabels[$row->quality_status] ?? $row->quality_status ?? '-',
            implode('、', $statuses),
        ];
    }

    public function styles(Worksheet $sheet): array
    {
        return [
            1 => ['font' => ['bold' => true]],
        ];
    }
}
