<?php

namespace App\Modules\Finance\Services;

use App\Modules\Finance\Contracts\FinanceServiceInterface;
use App\Modules\Finance\Models\UtilityFee;
use App\Modules\Procurement\Contracts\ProcurementServiceInterface;
use Illuminate\Support\Collection;
use Illuminate\Support\Carbon;

class FinanceService implements FinanceServiceInterface
{
    protected $procurementService;

    public function __construct(ProcurementServiceInterface $procurementService)
    {
        $this->procurementService = $procurementService;
    }

    public function getAccountingReportData(string $start, string $end): array
    {
        // 1. 獲取應付帳款資料 (已付款)
        $accountPayables = \App\Modules\Finance\Models\AccountPayable::where('status', \App\Modules\Finance\Models\AccountPayable::STATUS_PAID)
            ->whereNotNull('paid_at')
            ->whereBetween('paid_at', [$start, $end])
            ->get();

        // 取得供應商資料 (Manual Hydration)
        $vendorIds = $accountPayables->pluck('vendor_id')->unique()->filter()->toArray();
        $vendorsMap = $this->procurementService->getVendorsByIds($vendorIds)->keyBy('id');

        // 付款方式對映
        $paymentMethodMap = [
            'cash' => '現金',
            'bank_transfer' => '銀行轉帳',
            'check' => '支票',
            'credit_card' => '信用卡',
        ];

        $payableRecords = $accountPayables->map(function ($ap) use ($vendorsMap, $paymentMethodMap) {
            $vendorName = isset($vendorsMap[$ap->vendor_id]) ? $vendorsMap[$ap->vendor_id]->name : '未知廠商';
            $mappedPaymentMethod = $paymentMethodMap[$ap->payment_method] ?? $ap->payment_method;
            return [
                'id' => 'AP-' . $ap->id,
                'date' => Carbon::parse($ap->paid_at)->timezone(config('app.timezone'))->toDateString(),
                'source' => '應付帳款',
                'category' => '進貨支出',
                'item' => $vendorName,
                'reference' => $ap->document_number,
                'invoice_date' => $ap->invoice_date ? $ap->invoice_date->format('Y-m-d') : null,
                'invoice_number' => $ap->invoice_number,
                'amount' => (float)$ap->total_amount,
                'tax_amount' => (float)$ap->tax_amount,
                'status' => $ap->status,
                'payment_method' => $mappedPaymentMethod,
                'payment_note' => $ap->payment_note,
                'remarks' => $ap->remarks,
            ];
        });

        // 2. 獲取公共事業費 (已繳費)
        $utilityFees = UtilityFee::where('payment_status', UtilityFee::STATUS_PAID)
            ->whereBetween('transaction_date', [$start, $end])
            ->get()
            ->map(function ($fee) {
                return [
                    'id' => 'UF-' . $fee->id,
                    'date' => $fee->transaction_date->format('Y-m-d'),
                    'source' => '公共事業費',
                    'category' => $fee->category,
                    'item' => $fee->description ?: $fee->category,
                    'reference' => '-',
                    'invoice_date' => null,
                    'invoice_number' => $fee->invoice_number,
                    'amount' => (float)$fee->amount,
                    'tax_amount' => 0.0,
                    'status' => $fee->payment_status,
                    'payment_method' => null,
                    'payment_note' => null,
                    'remarks' => $fee->description,
                ];
            });

        $allRecords = $payableRecords->concat($utilityFees)
            ->sortByDesc('date')
            ->values();

        return [
            'records' => $allRecords,
            'summary' => [
                'total_amount' => $allRecords->sum('amount'),
                'payable_total' => $payableRecords->sum('amount'),
                'utility_total' => $utilityFees->sum('amount'),
                'record_count' => $allRecords->count(),
            ]
        ];
    }

    public function getUtilityFees(array $filters)
    {
        $query = UtilityFee::withCount('attachments');

        if (!empty($filters['search'])) {
            $search = $filters['search'];
            $query->where(function($q) use ($search) {
                $q->where('category', 'like', "%{$search}%")
                  ->orWhere('invoice_number', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        if (!empty($filters['category']) && $filters['category'] !== 'all') {
            $query->where('category', $filters['category']);
        }

        if (!empty($filters['date_start'])) {
            $query->where('transaction_date', '>=', $filters['date_start']);
        }

        if (!empty($filters['date_end'])) {
            $query->where('transaction_date', '<=', $filters['date_end']);
        }

        $sortField = $filters['sort_field'] ?? 'created_at';
        $sortDirection = $filters['sort_direction'] ?? 'desc';
        $query->orderBy($sortField, $sortDirection);

        $defaultPerPage = \App\Modules\Core\Models\SystemSetting::getVal('display.per_page', 10);
        $perPage = (int) ($filters['per_page'] ?? $defaultPerPage);
        if (!in_array($perPage, [10, 20, 50, 100])) {
            $perPage = $defaultPerPage;
        }

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

    public function getUniqueCategories(): Collection
    {
        return UtilityFee::distinct()->pluck('category');
    }
}
