<?php
namespace App\Controllers;

class Units extends BaseController
{
    public function index(int $facilityId)
    {
        $facility = $this->db->table('facilities')->where('id',$facilityId)->get()->getRowArray();
        if (!$facility) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();

        $statusFilter = $this->request->getGet('status') ?? '';
        $q = $this->db->table('units')->where('facility_id',$facilityId);
        if ($statusFilter) $q->where('status',$statusFilter);
        $units = $q->orderBy('unit_number','ASC')->get()->getResultArray();

        $kpi = [
            'total'       => $this->db->table('units')->where('facility_id',$facilityId)->countAllResults(),
            'occupied'    => $this->db->table('units')->where('facility_id',$facilityId)->where('status','occupied')->countAllResults(),
            'vacant'      => $this->db->table('units')->where('facility_id',$facilityId)->where('status','vacant')->countAllResults(),
            'maintenance' => $this->db->table('units')->where('facility_id',$facilityId)->where('status','maintenance')->countAllResults(),
        ];
        $kpi['occupancy_pct'] = $kpi['total'] > 0 ? round(($kpi['occupied']/$kpi['total'])*100) : 0;

        return view('units/index', $this->viewData([
            'title'        => $facility['name'].' — Units',
            'facility'     => $facility,
            'units'        => $units,
            'kpi'          => $kpi,
            'statusFilter' => $statusFilter,
        ]));
    }

    public function create(int $facilityId)
    {
        $facility = $this->db->table('facilities')->where('id',$facilityId)->get()->getRowArray();
        if (!$facility) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        return view('units/create', $this->viewData(['title'=>'Add Unit','facility'=>$facility]));
    }

    public function store(int $facilityId)
    {
        $rules = [
            'unit_number' => 'required|max_length[50]',
            'status'      => 'required|in_list[occupied,vacant,maintenance]',
        ];
        if (!$this->validate($rules)) return redirect()->back()->withInput()->with('errors',$this->validator->getErrors());

        $contractEnd = $this->request->getPost('contract_end') ?: null;

        $this->db->table('units')->insert([
            'facility_id'      => $facilityId,
            'unit_number'      => esc($this->request->getPost('unit_number')),
            'floor'            => esc($this->request->getPost('floor')       ?? ''),
            'unit_type'        => esc($this->request->getPost('unit_type')   ?? ''),
            'area_sqft'        => $this->request->getPost('area_sqft')        ?: null,
            // Owner info
            'owner_name'       => esc($this->request->getPost('owner_name')   ?? ''),
            'owner_mobile'     => esc($this->request->getPost('owner_mobile') ?? ''),
            'owner_email'      => esc($this->request->getPost('owner_email')  ?? ''),
            // Tenant info
            'tenant_name'      => esc($this->request->getPost('tenant_name')   ?? ''),
            'tenant_mobile'    => esc($this->request->getPost('tenant_mobile') ?? ''),
            'tenant_email'     => esc($this->request->getPost('tenant_email')  ?? ''),
            // Contract
            'contract_number'  => esc($this->request->getPost('contract_number') ?? ''),
            'contract_start'   => $this->request->getPost('contract_start')  ?: null,
            'contract_end'     => $contractEnd,
            // Financial
            'rent_amount'      => $this->request->getPost('rent_amount')      ?: null,
            'security_deposit' => $this->request->getPost('security_deposit') ?: null,
            'status'           => $this->request->getPost('status'),
            'notes'            => esc($this->request->getPost('notes') ?? ''),
            'created_by'       => session()->get('user_id'),
        ]);
        $unitId = $this->db->insertID();

        // Handle contract attachment upload
        $file = $this->request->getFile('contract_attachment');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $allowed = ['application/pdf','image/jpeg','image/png','image/webp'];
            if (in_array($file->getMimeType(),$allowed) && $file->getSize() <= 10*1024*1024) {
                $dir = WRITEPATH.'uploads/contracts/';
                if (!is_dir($dir)) mkdir($dir,0755,true);
                $name = 'unit_'.$unitId.'_'.time().'.'.$file->getExtension();
                $file->move($dir,$name);
                $this->db->table('units')->where('id',$unitId)->update(['contract_attachment'=>'uploads/contracts/'.$name]);
            }
        }

        // Auto-create contract record if tenant present
        if (!empty($this->request->getPost('tenant_name')) && !empty($this->request->getPost('contract_start')) && $contractEnd) {
            $conNum = $this->generateNumber('CON','contracts','contract_number');
            $this->db->table('contracts')->insert([
                'contract_number' => $conNum,
                'facility_id'     => $facilityId,
                'unit_id'         => $unitId,
                'client_name'     => esc($this->request->getPost('tenant_name')),
                'client_email'    => esc($this->request->getPost('tenant_email')  ?? ''),
                'client_mobile'   => esc($this->request->getPost('tenant_mobile') ?? ''),
                'contract_type'   => 'tenancy',
                'start_date'      => $this->request->getPost('contract_start'),
                'end_date'        => $contractEnd,
                'value'           => $this->request->getPost('rent_amount') ?: 0,
                'status'          => 'active',
                'created_by'      => session()->get('user_id'),
            ]);
        }

        $this->logActivity('create','units',$unitId);
        return redirect()->to(base_url('facilities/'.$facilityId.'/units'))->with('success','Unit added successfully.');
    }

    public function view(int $id)
    {
        $unit = $this->db->table('units u')
            ->select('u.*, f.name as facility_name, f.id as facility_id')
            ->join('facilities f','f.id=u.facility_id','left')
            ->where('u.id',$id)->get()->getRowArray();
        if (!$unit) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();

        $workOrders = $this->db->table('work_orders w')
            ->select('w.id, w.wo_number, w.title, w.status, w.priority, w.created_at, u.name as assigned_name')
            ->join('users u','u.id=w.assigned_to','left')
            ->where('w.unit_id',$id)
            ->orderBy('w.created_at','DESC')->limit(10)->get()->getResultArray();

        $contract = $this->db->table('contracts')
            ->where('unit_id',$id)->where('status','active')
            ->orderBy('created_at','DESC')->limit(1)->get()->getRowArray();

        $checklists = $this->db->table('unit_checklists uc')
            ->select('uc.*, u.name as created_by_name')
            ->join('users u','u.id=uc.created_by','left')
            ->where('uc.unit_id',$id)
            ->orderBy('uc.created_at','DESC')->get()->getResultArray();

        $daysToExpiry = null;
        if ($unit['contract_end']) {
            $daysToExpiry = (int)ceil((strtotime($unit['contract_end']) - time()) / 86400);
        }

        return view('units/view', $this->viewData([
            'title'        => 'Unit '.$unit['unit_number'],
            'unit'         => $unit,
            'workOrders'   => $workOrders,
            'contract'     => $contract,
            'checklists'   => $checklists,
            'daysToExpiry' => $daysToExpiry,
        ]));
    }

    public function edit(int $id)
    {
        $unit = $this->db->table('units u')
            ->select('u.*, f.name as facility_name')
            ->join('facilities f','f.id=u.facility_id','left')
            ->where('u.id',$id)->get()->getRowArray();
        if (!$unit) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        return view('units/edit', $this->viewData(['title'=>'Edit Unit '.$unit['unit_number'],'unit'=>$unit]));
    }

    public function update(int $id)
    {
        $unit = $this->db->table('units')->where('id',$id)->get()->getRowArray();
        if (!$unit) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();

        $this->db->table('units')->where('id',$id)->update([
            'unit_number'      => esc($this->request->getPost('unit_number')),
            'floor'            => esc($this->request->getPost('floor')       ?? ''),
            'unit_type'        => esc($this->request->getPost('unit_type')   ?? ''),
            'area_sqft'        => $this->request->getPost('area_sqft')        ?: null,
            'owner_name'       => esc($this->request->getPost('owner_name')   ?? ''),
            'owner_mobile'     => esc($this->request->getPost('owner_mobile') ?? ''),
            'owner_email'      => esc($this->request->getPost('owner_email')  ?? ''),
            'tenant_name'      => esc($this->request->getPost('tenant_name')   ?? ''),
            'tenant_mobile'    => esc($this->request->getPost('tenant_mobile') ?? ''),
            'tenant_email'     => esc($this->request->getPost('tenant_email')  ?? ''),
            'contract_number'  => esc($this->request->getPost('contract_number') ?? ''),
            'contract_start'   => $this->request->getPost('contract_start')  ?: null,
            'contract_end'     => $this->request->getPost('contract_end')    ?: null,
            'rent_amount'      => $this->request->getPost('rent_amount')      ?: null,
            'security_deposit' => $this->request->getPost('security_deposit') ?: null,
            'status'           => $this->request->getPost('status'),
            'notes'            => esc($this->request->getPost('notes') ?? ''),
        ]);

        // Handle new contract attachment
        $file = $this->request->getFile('contract_attachment');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $allowed = ['application/pdf','image/jpeg','image/png','image/webp'];
            if (in_array($file->getMimeType(),$allowed) && $file->getSize() <= 10*1024*1024) {
                $dir = WRITEPATH.'uploads/contracts/';
                if (!is_dir($dir)) mkdir($dir,0755,true);
                $name = 'unit_'.$id.'_'.time().'.'.$file->getExtension();
                $file->move($dir,$name);
                $this->db->table('units')->where('id',$id)->update(['contract_attachment'=>'uploads/contracts/'.$name]);
            }
        }

        $this->logActivity('update','units',$id);
        return redirect()->to(base_url('units/view/'.$id))->with('success','Unit updated successfully.');
    }

    public function delete(int $id)
    {
        $this->requireRole('super_admin','facility_manager');
        $unit = $this->db->table('units')->where('id',$id)->get()->getRowArray();
        if (!$unit) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        $facilityId = $unit['facility_id'];
        $this->db->table('units')->where('id',$id)->update(['deleted_at'=>date('Y-m-d H:i:s'),'status'=>'vacant']);
        $this->logActivity('delete','units',$id);
        return redirect()->to(base_url('facilities/'.$facilityId.'/units'))->with('success','Unit removed.');
    }

    public function checklist(int $unitId, string $type)
    {
        $unit = $this->db->table('units u')->select('u.*, f.name as facility_name')->join('facilities f','f.id=u.facility_id','left')->where('u.id',$unitId)->get()->getRowArray();
        if (!$unit) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        $validTypes = ['move_in','move_out','routine','handover'];
        if (!in_array($type,$validTypes)) $type = 'routine';
        $existing = $this->db->table('unit_checklists')->where('unit_id',$unitId)->where('type',$type)->where('status','draft')->orderBy('created_at','DESC')->limit(1)->get()->getRowArray();
        return view('units/checklist', $this->viewData(['title'=>ucfirst(str_replace('_',' ',$type)).' Checklist','unit'=>$unit,'type'=>$type,'checklist'=>$existing]));
    }

    public function storeChecklist()
    {
        $unitId = (int)$this->request->getPost('unit_id');
        $type   = $this->request->getPost('type');
        $unit   = $this->db->table('units')->where('id',$unitId)->get()->getRowArray();
        if (!$unit) return redirect()->back()->with('error','Unit not found.');

        $items   = $this->request->getPost('items') ?? [];
        $notes   = $this->request->getPost('item_notes') ?? [];
        $encoded = json_encode(['items'=>$items,'notes'=>$notes]);

        $this->db->table('unit_checklists')->insert([
            'unit_id'    => $unitId,
            'type'       => $type,
            'items_json' => $encoded,
            'notes'      => esc($this->request->getPost('general_notes') ?? ''),
            'status'     => $this->request->getPost('submit_action') === 'complete' ? 'completed' : 'draft',
            'created_by' => session()->get('user_id'),
        ]);
        $clId = $this->db->insertID();

        // Update unit status based on checklist type
        if ($type === 'move_in') {
            $this->db->table('units')->where('id',$unitId)->update(['status'=>'occupied']);
        } elseif ($type === 'move_out') {
            $this->db->table('units')->where('id',$unitId)->update(['status'=>'vacant','tenant_name'=>'','tenant_mobile'=>'','tenant_email'=>'']);
        }

        $this->logActivity('create','unit_checklists',$clId,"$type checklist for unit {$unit['unit_number']}");
        return redirect()->to(base_url('units/view/'.$unitId))->with('success',ucfirst(str_replace('_',' ',$type)).' checklist saved.');
    }

    public function printChecklist(int $id)
    {
        $cl = $this->db->table('unit_checklists uc')
            ->select('uc.*, u.unit_number, u.floor, f.name as facility_name')
            ->join('units u', 'u.id=uc.unit_id', 'left')
            ->join('facilities f', 'f.id=u.facility_id', 'left')
            ->where('uc.id', $id)
            ->get()
            ->getRowArray();
        if (!$cl) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }
        $unitRow = $this->db->table('units')->select('facility_id')->where('id', $cl['unit_id'])->get()->getRowArray();
        if ($unitRow) {
            $this->assertFacilityAccess((int) $unitRow['facility_id']);
        }

        $decoded = json_decode($cl['items_json'] ?? '{}', true) ?: [];
        $rawItems = $decoded['items'] ?? [];
        $rawNotes = $decoded['notes'] ?? [];
        $printItems = [];
        foreach ($rawItems as $i => $label) {
            if (! trim((string) $label)) {
                continue;
            }
            $printItems[] = [
                'label'   => $label,
                'checked' => true,
                'notes'   => $rawNotes[$i] ?? '',
            ];
        }

        return view('compliance/checklist_print', $this->viewData([
            'checklistTitle' => ucfirst(str_replace('_', ' ', $cl['type'])) . ' — ' . $cl['unit_number'],
            'checklistType'  => $cl['type'],
            'unitRef'        => $cl['unit_number'] . ($cl['floor'] ? ' / ' . $cl['floor'] : ''),
            'facilityName'   => $cl['facility_name'],
            'inspectionDate' => date('d M Y', strtotime($cl['created_at'])),
            'refNumber'      => 'UC-' . $cl['id'],
            'sections'       => [['title' => 'Checklist Items', 'items' => $printItems]],
            'usePdf'         => true,
        ]));
    }
}
