<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use App\Models\UnitAssignment;
use Carbon\Carbon;

class RentRollExport implements FromCollection, WithHeadings, WithMapping, WithTitle, ShouldAutoSize, WithStyles
{
    protected $date;
    protected $propertyId;
    protected $assignments;

    public function __construct($date, $propertyId = null)
    {
        $this->date = $date;
        $this->propertyId = $propertyId;
        
        $query = UnitAssignment::with([
            'unit.property',
            'customer',
            'payments' => function($q) use ($date) {
                $q->whereMonth('PaymentDate', '=', date('m', strtotime($date)))
                  ->whereYear('PaymentDate', '=', date('Y', strtotime($date)));
            }
        ])
        ->where('start_date', '<=', $date)
        ->where(function($q) use ($date) {
            $q->whereNull('end_date')
              ->orWhere('end_date', '>=', $date);
        });
        
        if ($propertyId) {
            $query->whereHas('unit', function($q) use ($propertyId) {
                $q->where('PropID', $propertyId);
            });
        }
        
        $this->assignments = $query->get();
    }

    public function collection()
    {
        return $this->assignments->map(function($assignment) {
            $paidAmount = $assignment->payments->sum('Amount');
            $outstanding = $assignment->MonthlyRent - $paidAmount;
            $status = $outstanding <= 0 ? 'Paid' : 
                     ($paidAmount > 0 ? 'Partial' : 'Unpaid');
            
            return (object)[
                'tenant' => $assignment->customer->CustomerName ?? 'N/A',
                'property' => $assignment->unit->property->PropertyName ?? 'N/A',
                'unit' => $assignment->unit->UnitName ?? 'N/A',
                'monthly_rent' => $assignment->MonthlyRent,
                'paid_amount' => $paidAmount,
                'outstanding' => $outstanding,
                'status' => $status,
                'phone' => $assignment->customer->CustomerPhone ?? 'N/A',
                'email' => $assignment->customer->CustomerEmail ?? 'N/A',
                'start_date' => $assignment->StartDate,
                'end_date' => $assignment->EndDate
            ];
        });
    }

    public function headings(): array
    {
        return [
            'Tenant Name',
            'Property',
            'Unit',
            'Monthly Rent',
            'Paid Amount',
            'Outstanding',
            'Status',
            'Phone',
            'Email',
            'Lease Start',
            'Lease End'
        ];
    }

    public function map($row): array
    {
        return [
            $row->tenant,
            $row->property,
            $row->unit,
            $row->monthly_rent,
            $row->paid_amount,
            $row->outstanding,
            $row->status,
            $row->phone,
            $row->email,
            $row->start_date ? Carbon::parse($row->start_date)->format('M d, Y') : 'N/A',
            $row->end_date ? Carbon::parse($row->end_date)->format('M d, Y') : 'Ongoing'
        ];
    }

    public function title(): string
    {
        return 'Rent Roll ' . Carbon::parse($this->date)->format('F Y');
    }

    public function styles(Worksheet $sheet)
    {
        // Style the header row
        $sheet->getStyle('A1:K1')->applyFromArray([
            'font' => ['bold' => true],
            'fill' => [
                'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                'startColor' => ['rgb' => 'D9EAD3']
            ]
        ]);

        // Style currency columns
        $sheet->getStyle('D2:F' . ($this->assignments->count() + 1))->getNumberFormat()->setFormatCode('K#,##0.00');

        // Add conditional formatting for status column (simplified approach)
        $statusColumn = 'G';
        $lastRow = $this->assignments->count() + 1;
        
        // Apply different styles based on status
        for ($row = 2; $row <= $lastRow; $row++) {
            $cell = $statusColumn . $row;
            $status = $sheet->getCell($cell)->getValue();
            
            $style = [];
            
            switch ($status) {
                case 'Paid':
                    $style = [
                        'font' => ['color' => ['rgb' => '155724']],
                        'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => 'C3E6CB']]
                    ];
                    break;
                case 'Partial':
                    $style = [
                        'font' => ['color' => ['rgb' => '856404']],
                        'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => 'FFEEBA']]
                    ];
                    break;
                case 'Unpaid':
                    $style = [
                        'font' => ['color' => ['rgb' => '721C24']],
                        'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => 'F5C6CB']]
                    ];
                    break;
            }
            
            if (!empty($style)) {
                $sheet->getStyle($cell)->applyFromArray($style);
            }
        }

        // Auto-filter
        $sheet->setAutoFilter($sheet->calculateWorksheetDimension());

        // Freeze the first row
        $sheet->freezePane('A2');

        return [];
    }
}
