<?php

namespace App\Exports;

use Carbon\Carbon;
use App\Models\CashReceipt;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Validators\Failure;

class ExportCashReceiptReport implements FromCollection, WithHeadings, WithStyles, ShouldAutoSize
{
    protected $slug;
    protected $vin;

    public function __construct($slug, $vin = null) {
        $this->slug = $slug;
        $this->vin = $vin;
    }

    public function collection(){
        $cash_receipt = CashReceipt::select(
            'cash_receipt.id',
            'cash_receipt.obf_id as cash_receipt_obf_id',
            'obf.id as obf_id',
            'obf.customer_name as customer_name',
            'branches.id as branch_id',
            'branches.name as branch_name',
            DB::raw("CONCAT(us.first_name,' ',us.last_name) AS kec_name"),
            'obf.contact_number',
            DB::raw("DATE_FORMAT(cash_receipt.created_at, '%d-%m-%Y') AS receipt_date"),
            'cash_receipt.amount as receipt_amount',
            DB::raw("CASE 
                WHEN cash_receipt.receipt_type = 'booking_receipt' THEN 'Booking Receipt'
                WHEN cash_receipt.receipt_type = 'downpayment_receipt' THEN 'Downpayment Receipt'
                WHEN cash_receipt.receipt_type = 'disbursement_receipt' THEN 'Disbursement Receipt'
                WHEN cash_receipt.receipt_type = 'other_receipt' THEN 'Other Receipt'
                ELSE cash_receipt.receipt_type
            END as receipt_type"),
            DB::raw("CASE 
                WHEN cash_receipt.payment_type = 'online_transfer' THEN 'Online Transfer'
                WHEN cash_receipt.payment_type = 'cash' THEN 'Cash'
                WHEN cash_receipt.payment_type = 'cheque' THEN 'Cheque'
                WHEN cash_receipt.payment_type = 'vallet_payment' THEN 'Vallet Payment'
                ELSE cash_receipt.payment_type
            END as payment_type"),
            'bank_account.name as bank_account_no',
            'finance.name AS hyp',
            'cash_receipt.transaction_no',
            'products.id as product_id',
            'car_model.name as model_name',
            'car_varient.name as varient_name',
            DB::raw('(SELECT vin_number FROM inventory WHERE inventory.status = "allocated" AND inventory.id = obf.inventory_id) as vin_number'),
            DB::raw("CONCAT(exteriorcolor.name, ' | ', interiorcolor.name) as combined_color"),
            'cash_receipt.status',
            'cash_receipt.cash_remark',
        )
        ->join('obf', 'cash_receipt.obf_id', 'obf.id')
        ->leftJoin('branches', 'obf.branch_id', 'branches.id')
        ->leftJoin('products', 'obf.product_id', 'products.id')
        ->leftJoin('car_model', 'products.car_model', 'car_model.id')
        ->leftJoin('car_varient', 'products.veriant', 'car_varient.id')
        ->leftJoin('exteriorcolor','exteriorcolor.id','=','products.exterior_color')
        ->leftJoin('interiorcolor','interiorcolor.id','=','products.interior_color')
        ->leftjoin('users as us','us.id','obf.sales_person_id')
        ->leftjoin('Team_master','Team_master.id','us.team_name')
        ->leftjoin('inventory', 'inventory.name', '=', 'products.id')
        ->leftjoin('bank_account', 'bank_account.id', 'cash_receipt.bank_account_id')
        ->leftjoin('obf_finance', 'obf.id', 'obf_finance.obf_id')
        ->leftjoin('finance', 'obf_finance.finance_name', 'finance.id')
        ->where('cash_receipt.status','accepted')
        ->groupBy('cash_receipt.id')
        ->get();
        
        $data = $cash_receipt->map(function ($receipt) {
            $receipt_id = $receipt->id ?? '';
            $branch_full = $receipt->branch_name ?? '';
            $month = Carbon::parse($receipt->created_at)->format('m');
            $year = Carbon::parse($receipt->created_at)->format('Y');
            $b_name = '';
    
            if (str_contains($branch_full, 'Rajkot')) {
                $b_name = 'RJT';
            } elseif (str_contains($branch_full, 'Jamnagar')) {
                $b_name = 'Jam';
            } elseif (str_contains($branch_full, 'Junagadh')) {
                $b_name = 'Juna';
            } elseif (str_contains($branch_full, 'Morbi')) {
                $b_name = 'Mor';
            }
    
            $receipt_no = $receipt_id . $b_name . $month . $year;
    
            return [
                $receipt->id,
                $receipt->branch_name,
                $receipt->kec_name,
                $receipt->customer_name,
                $receipt->contact_number,
                $receipt->receipt_date,
                $receipt_no,
                $receipt->receipt_amount,
                $receipt->receipt_type,
                $receipt->payment_type,
                $receipt->bank_account_no,
                $receipt->hyp,
                $receipt->transaction_no,
                $receipt->model_name,
                $receipt->varient_name,
                $receipt->vin_number,
                $receipt->combined_color,
                \Illuminate\Support\Str::ucfirst($receipt->status),
                $receipt->cash_remark,
            ];
        });
        
        if ($data->isEmpty()) {
            throw new \ErrorException('No Data Found!');
        }

        return collect($data);

    }

    public function headings(): array
    {
        return [
            "No.",
            "Location",
            "KEC Name",
            "Customer Name",
            "Customer Mobile No.",
            "Receipt Date",
            "Receipt No.",
            "Receipt Amount",
            "Receipt Type",
            "Payment Type",
            "Bank Account No.",
            "Hyp.",
            "Transaction No.",
            "Model",
            "Varient",
            "VIN No.",
            "Color",
            "Status",
            "Remark"
        ];
    }

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

    public function onFailure(Failure ...$failures)
    {
        $exception = ValidationException::withMessages(collect($failures)->map->toArray()->all());
        dd($exception);
        throw $exception;
    }
}
