<?php

namespace App\Http\Controllers\Api\V1\Showroom;

use App\Http\Controllers\Controller;
use App\Models\ShowroomCashClosing;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class CashClosingController extends Controller
{
    public function summary(Request $request)
    {
        $date = $request->query('date', now()->toDateString());

        return response()->json($this->summaryForDate($date));
    }

    public function close(Request $request)
    {
        $data = $request->validate([
            'business_date' => 'nullable|date',
            'opening_cash' => 'nullable|numeric|min:0',
            'counted_cash' => 'required|numeric|min:0',
            'note' => 'nullable|string',
        ]);
        $admin = $request->attributes->get('showroom_admin');
        $date = $data['business_date'] ?? now()->toDateString();
        $summary = $this->summaryForDate($date);
        $expected = (float) ($data['opening_cash'] ?? 0) + (float) $summary['cash_sales'] - (float) $summary['cash_refunds'];

        $closing = ShowroomCashClosing::create([
            'closing_no' => 'CLOSE-' . now()->format('ymdHis') . '-' . random_int(1000, 9999),
            'business_date' => $date,
            'showroom_id' => $request->query('showroom_id'),
            'closed_by_admin_id' => $admin?->id,
            'opening_cash' => (float) ($data['opening_cash'] ?? 0),
            'cash_sales' => $summary['cash_sales'],
            'cash_refunds' => $summary['cash_refunds'],
            'expected_cash' => $expected,
            'counted_cash' => (float) $data['counted_cash'],
            'difference_amount' => round((float) $data['counted_cash'] - $expected, 8),
            'note' => $data['note'] ?? null,
        ]);

        foreach ($summary['by_payment_method'] as $method => $row) {
            DB::table('showroom_cash_closing_payments')->insert([
                'showroom_cash_closing_id' => $closing->id,
                'payment_method' => $method,
                'amount' => $row['amount'],
                'transaction_count' => $row['count'],
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }

        return response()->json($closing, 201);
    }

    private function summaryForDate(string $date): array
    {
        $rows = DB::table('order_payments')
            ->join('orders', 'orders.id', '=', 'order_payments.order_id')
            ->where('orders.sale_channel', 'showroom')
            ->whereDate('order_payments.created_at', $date)
            ->where('order_payments.payment_status', 'paid')
            ->select('order_payments.payment_method', DB::raw('SUM(order_payments.amount) as amount'), DB::raw('COUNT(*) as count'))
            ->groupBy('order_payments.payment_method')
            ->get();

        $byMethod = $rows->mapWithKeys(fn ($row) => [
            $row->payment_method => [
                'amount' => (float) $row->amount,
                'count' => (int) $row->count,
            ],
        ])->all();

        $cashRefunds = 0;
        if (Schema::hasTable('refunds') && Schema::hasColumn('orders', 'sale_channel')) {
            $cashRefunds = (float) DB::table('refunds')
                ->join('orders', 'orders.id', '=', 'refunds.order_id')
                ->where('orders.sale_channel', 'showroom')
                ->whereDate('refunds.created_at', $date)
                ->where('refunds.refund_method', 'cash')
                ->whereIn('refunds.refund_status', ['refunded', 'approved'])
                ->sum('refunds.refund_amount');
        }

        return [
            'date' => $date,
            'cash_sales' => (float) data_get($byMethod, 'cash.amount', 0),
            'cash_refunds' => round($cashRefunds, 8),
            'total_collection' => (float) collect($byMethod)->sum('amount'),
            'by_payment_method' => $byMethod,
        ];
    }
}
