<?php

namespace App\Imports;

use App\Models\CashRegister;
use App\Models\CashTransaction;
use App\Models\ChartOfAccount;
use App\Models\Elevator;
use App\Http\Controllers\CashTransactionController;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

use Maatwebsite\Excel\Concerns\SkipsEmptyRows;

class CashDepositsImport implements ToCollection, WithHeadingRow, WithValidation, SkipsEmptyRows
{
    /**
     * @param Collection $rows
     */
    public function collection(Collection $rows)
    {
        $user = Auth::user();
        $company_id = $user->company_id;
        $controller = new CashTransactionController();

        foreach ($rows as $row) {
            DB::beginTransaction();
            try {
                // Find Cash Register by name or ID
                $cashRegister = CashRegister::where('company_id', $company_id)
                    ->where(function ($query) use ($row) {
                        $query->where('id', $row['cash_register'])
                              ->orWhere('name', $row['cash_register']);
                    })->first();

                if (!$cashRegister) {
                    Log::warning("Cash Register not found: " . $row['cash_register']);
                    DB::rollBack();
                    continue;
                }

                // Find Party Account by name or ID
                $partyAccount = ChartOfAccount::where('company_id', $company_id)
                    ->where(function ($query) use ($row) {
                        $query->where('id', $row['party_name'])
                              ->orWhere('name', $row['party_name'])
                              ->orWhere('name_en', $row['party_name']);
                    })->first();

                if (!$partyAccount) {
                    Log::warning("Party Account not found: " . $row['party_name']);
                    DB::rollBack();
                    continue;
                }

                // Find Elevator if provided
                $elevatorId = null;
                if (!empty($row['elevator'])) {
                    $elevator = Elevator::where('company_id', $company_id)
                        ->where(function ($query) use ($row) {
                            $query->where('id', $row['elevator'])
                                  ->orWhere('serial_number', $row['elevator']);
                        })->first();
                    $elevatorId = $elevator ? $elevator->id : null;
                }

                $transaction = new CashTransaction([
                    'cash_register_id' => $cashRegister->id,
                    'company_id' => $company_id,
                    'user_id' => $user->id,
                    'type' => 'deposit',
                    'amount' => $row['amount'],
                    'receipt_date' => $row['date'] ?? now(),
                    'party_name' => $partyAccount->name, // We use the account name
                    'party_type' => $row['party_type'] ?? 'other',
                    'elevator_id' => $elevatorId,
                    'notes' => $row['notes'] ?? null,
                ]);

                $transaction->save();

                // Update Cash Register Balance
                $cashRegister->current_balance += $row['amount'];
                $cashRegister->save();

                // Create Journal Entry
                $entry = $controller->createJournalEntryForDeposit($transaction);

                if (!$entry) {
                    throw new \Exception("Failed to create journal entry for transaction at row " . ($rows->keys()[$rows->search($row)] + 2));
                }

                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
                Log::error("Error importing cash deposit row: " . $e->getMessage());
            }
        }
    }

    /**
     * Validation Rules
     */
    public function rules(): array
    {
        return [
            'cash_register' => 'required',
            'amount' => 'required|numeric|min:0.01',
            'party_name' => 'required',
            'date' => 'nullable|date',
        ];
    }
}
