<?php

namespace App\Modules\Inventory\Services;

use App\Modules\Inventory\Models\InventoryTransaction;
use App\Modules\Inventory\Models\Product; // Use Inventory module's Product if available, or Core's? Usually Product is in Inventory/Models? No, let's check. 
// Checking Product model location... likely App\Modules\Product\Models\Product or App\Modules\Inventory\Models\Product.
// From previous context: "products.create" permission suggests a Products module.
// But stock query uses `products` table join.
// Let's assume standard Laravel query builder or check existing models.
// StockQueryController uses `InventoryService`.
// I will use DB facade or InventoryTransaction model for aggregation.

use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Builder;

class InventoryReportService
{
    /**
     * 取得庫存報表資料
     *
     * @param array $filters 篩選條件
     * @param int|null $perPage 每頁筆數
     * @return \Illuminate\Pagination\LengthAwarePaginator|\Illuminate\Support\Collection
     */
    public function getReportData(array $filters, ?int $perPage = 10)
    {
        $dateFrom = $filters['date_from'] ?? null;
        $dateTo = $filters['date_to'] ?? null;
        $warehouseId = $filters['warehouse_id'] ?? null;
        $categoryId = $filters['category_id'] ?? null;
        $search = $filters['search'] ?? null;
        $sortBy = $filters['sort_by'] ?? 'product_code';
        $sortOrder = $filters['sort_order'] ?? 'asc';

        // 若無任何篩選條件，直接回傳空資料
        if (!$dateFrom && !$dateTo && !$warehouseId && !$categoryId && !$search) {
             return new \Illuminate\Pagination\LengthAwarePaginator([], 0, $perPage ?: 10);
        }

        // 定義時間欄位轉換 (UTC -> Asia/Taipei)
        // 日期欄位：Laravel 時區已設為 Asia/Taipei，直接使用 actual_time
        $timeColumn = "inventory_transactions.actual_time";

        // 建立查詢
        // 我們需要針對每個 品項 在選定區間內 進行彙總
        // 來源：inventory_transactions -> inventory -> product
        
        $query = InventoryTransaction::query()
            ->select([
                'products.code as product_code',
                'products.name as product_name',
                'categories.name as category_name',
                'products.id as product_id',
                // 進貨量：type 為 入庫, 手動入庫 (排除 調撥入庫)
                DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('入庫', '手動入庫') AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as inbound_qty"),
                // 出貨量：type 為 出庫 (排除 調撥出庫) (取絕對值)
                DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type IN ('出庫') AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as outbound_qty"),
                // 調撥入：type 為 調撥入庫
                DB::raw("SUM(CASE WHEN inventory_transactions.type = '調撥入庫' AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as transfer_in_qty"),
                // 調撥出：type 為 調撥出庫 (取絕對值)
                DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type = '調撥出庫' AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as transfer_out_qty"),
                // 調整量：type 為 庫存調整, 手動編輯
                DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('庫存調整', '手動編輯') THEN inventory_transactions.quantity ELSE 0 END) as adjust_qty"),
                // 淨變動：總和 (包含所有類型：進貨、出貨、調整、調撥)
                DB::raw("SUM(inventory_transactions.quantity) as net_change"),
            ])
            ->join('inventories', 'inventory_transactions.inventory_id', '=', 'inventories.id')
            ->join('products', 'inventories.product_id', '=', 'products.id')
            ->leftJoin('categories', 'products.category_id', '=', 'categories.id');

        // 日期篩選：資料庫儲存的是台北時間，直接用字串比對
        if ($dateFrom && $dateTo) {
            $query->whereRaw("$timeColumn >= ? AND $timeColumn <= ?", [
                $dateFrom . ' 00:00:00',
                $dateTo . ' 23:59:59'
            ]);
        } elseif ($dateFrom) {
            $query->whereRaw("$timeColumn >= ?", [$dateFrom . ' 00:00:00']);
        } elseif ($dateTo) {
            $query->whereRaw("$timeColumn <= ?", [$dateTo . ' 23:59:59']);
        }

        // 應用篩選
        if ($warehouseId) {
            $query->where('inventories.warehouse_id', $warehouseId);
        }

        if ($categoryId) {
            $query->where('products.category_id', $categoryId);
        }

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('products.name', 'like', "%{$search}%")
                  ->orWhere('products.code', 'like', "%{$search}%");
            });
        }

        // 分組
        $query->groupBy([
            'products.id',
            'products.code',
            'products.name',
            'categories.name'
        ]);

        // 動態排序
        $allowedSortFields = [
            'product_code' => 'products.code',
            'product_name' => 'products.name',
            'inbound_qty' => 'inbound_qty',
            'outbound_qty' => 'outbound_qty',
            'transfer_in_qty' => 'transfer_in_qty',
            'transfer_out_qty' => 'transfer_out_qty',
            'adjust_qty' => 'adjust_qty',
            'net_change' => 'net_change',
        ];

        $sortColumn = $allowedSortFields[$sortBy] ?? 'products.code';
        $query->orderBy($sortColumn, $sortOrder === 'desc' ? 'desc' : 'asc');


        if ($perPage) {
            return $query->paginate($perPage)->withQueryString();
        }

        return $query->get();
    }

    /**
     * 取得報表統計數據 (不分頁，針對篩選條件的全量統計)
     */
    public function getSummary(array $filters)
    {
        $dateFrom = $filters['date_from'] ?? null;
        $dateTo = $filters['date_to'] ?? null;
        $warehouseId = $filters['warehouse_id'] ?? null;
        $categoryId = $filters['category_id'] ?? null;
        $search = $filters['search'] ?? null;

        // 若無任何篩選條件，直接回傳零值
        if (!$dateFrom && !$dateTo && !$warehouseId && !$categoryId && !$search) {
            return (object)[
                'total_inbound' => 0,
                'total_outbound' => 0,
                'total_adjust' => 0,
                'total_net_change' => 0,
            ];
        }
        // 日期欄位：Laravel 時區已設為 Asia/Taipei，直接使用 actual_time
        $timeColumn = "inventory_transactions.actual_time";

        $query = InventoryTransaction::query()
            ->join('inventories', 'inventory_transactions.inventory_id', '=', 'inventories.id')
            ->join('products', 'inventories.product_id', '=', 'products.id')
            ->leftJoin('categories', 'products.category_id', '=', 'categories.id');

        // 日期篩選：資料庫儲存的是台北時間，直接用字串比對
        if ($dateFrom && $dateTo) {
            $query->whereRaw("$timeColumn >= ? AND $timeColumn <= ?", [
                $dateFrom . ' 00:00:00',
                $dateTo . ' 23:59:59'
            ]);
        } elseif ($dateFrom) {
            $query->whereRaw("$timeColumn >= ?", [$dateFrom . ' 00:00:00']);
        } elseif ($dateTo) {
            $query->whereRaw("$timeColumn <= ?", [$dateTo . ' 23:59:59']);
        }

        if ($warehouseId) {
            $query->where('inventories.warehouse_id', $warehouseId);
        }

        if ($categoryId) {
            $query->where('products.category_id', $categoryId);
        }

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('products.name', 'like', "%{$search}%")
                  ->orWhere('products.code', 'like', "%{$search}%");
            });
        }

        // 直接聚合所有符合條件的交易
        return $query->select([
            DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('入庫', '手動入庫') AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as total_inbound"),
            DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type IN ('出庫') AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as total_outbound"),
            DB::raw("SUM(CASE WHEN inventory_transactions.type = '調撥入庫' AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as total_transfer_in"),
            DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type = '調撥出庫' AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as total_transfer_out"),
            DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('庫存調整', '手動編輯') THEN inventory_transactions.quantity ELSE 0 END) as total_adjust"),
            DB::raw("SUM(inventory_transactions.quantity) as total_net_change"),
        ])->first();
    }

    /**
     * 取得特定商品的庫存異動明細
     */
    public function getProductDetails($productId, array $filters, ?int $perPage = 20)
    {
        $dateFrom = $filters['date_from'] ?? null;
        $dateTo = $filters['date_to'] ?? null;
        $warehouseId = $filters['warehouse_id'] ?? null;
        // 日期欄位：Laravel 時區已設為 Asia/Taipei，直接使用 actual_time
        $timeColumn = "inventory_transactions.actual_time";

        $query = InventoryTransaction::query()
            ->select([
                'inventory_transactions.*',
                'inventories.warehouse_id',
                'inventories.batch_number as batch_no',
                'warehouses.name as warehouse_name',
                'users.name as user_name',
                'products.code as product_code',
                'products.name as product_name',
                'units.name as unit_name'
            ])
            ->join('inventories', 'inventory_transactions.inventory_id', '=', 'inventories.id')
            ->join('products', 'inventories.product_id', '=', 'products.id')
            ->leftJoin('units', 'products.base_unit_id', '=', 'units.id')
            ->leftJoin('warehouses', 'inventories.warehouse_id', '=', 'warehouses.id')
            ->leftJoin('users', 'inventory_transactions.user_id', '=', 'users.id')
            ->where('products.id', $productId);

        // 日期篩選：資料庫儲存的是台北時間，直接用字串比對
        if ($dateFrom && $dateTo) {
            $query->whereRaw("$timeColumn >= ? AND $timeColumn <= ?", [
                $dateFrom . ' 00:00:00',
                $dateTo . ' 23:59:59'
            ]);
        } elseif ($dateFrom) {
            $query->whereRaw("$timeColumn >= ?", [$dateFrom . ' 00:00:00']);
        } elseif ($dateTo) {
            $query->whereRaw("$timeColumn <= ?", [$dateTo . ' 23:59:59']);
        }

        if ($warehouseId) {
            $query->where('inventories.warehouse_id', $warehouseId);
        }

        // 排序：最新的在最上面
        $query->orderBy('inventory_transactions.actual_time', 'desc')
              ->orderBy('inventory_transactions.id', 'desc');

        return $query->paginate($perPage)->withQueryString();
    }
}
