<?php
namespace App\Controllers;

class QuotesController extends BaseController
{
    public function index()
    {
        if (!$this->can('view_quotes')) return redirect()->to('/')->with('error','Access denied');
        $db=$db=db_connect(); $cid=$this->companyId;
        $tab=$this->request->getGet('tab')??'all'; $search=$this->request->getGet('search'); $status=$this->request->getGet('status');
        $b=$db->table('quotes q')->select('q.*, c.first_name, c.last_name, c.company_name')->join('customers c','c.id=q.customer_id')->where('q.company_id',$cid);
        if ($tab==='deleted') $b->where('q.deleted_at IS NOT NULL',null,false);
        else { $b->where('q.deleted_at IS NULL',null,false); if ($status) $b->where('q.status',$status); }
        if ($search) $b->groupStart()->like('q.number',$search)->orLike('q.title',$search)->orLike('c.first_name',$search)->orLike('c.last_name',$search)->groupEnd();
        $quotes=$b->orderBy('q.created_at','DESC')->get()->getResultArray();
        $counts=['all'=>$db->table('quotes')->where('company_id',$cid)->where('deleted_at IS NULL',null,false)->countAllResults(),'sent'=>$db->table('quotes')->where('company_id',$cid)->where('deleted_at IS NULL',null,false)->where('status','sent')->countAllResults(),'deleted'=>$db->table('quotes')->where('company_id',$cid)->where('deleted_at IS NOT NULL',null,false)->countAllResults()];
        return $this->view('quotes/index', compact('quotes','counts','tab','search','status'));
    }

    public function show(int $id)
    {
        if (!$this->can('view_quotes')) return redirect()->to('/')->with('error','Access denied');
        $q=$this->getQuoteOr404($id); $db=db_connect();
        $q['customer']=$db->table('customers')->where('id',$q['customer_id'])->get()->getRowArray();
        $q['items']=$db->table('quote_items')->where('quote_id',$id)->orderBy('sort_order')->get()->getResultArray();
        $q['job']=$q['job_id']?$db->table('jobs')->where('id',$q['job_id'])->get()->getRowArray():null;
        $currency=$this->settings['regional']['currency']??'GBP';
        return $this->view('quotes/show', compact('q','currency'));
    }

    public function create()
    {
        if (!$this->can('edit_quotes')) return redirect()->to('/fieldly/public/index.php/quotes')->with('error','Access denied');
        $db=db_connect(); $cid=$this->companyId;
        $customers=$db->table('customers')->where('company_id',$cid)->where('status','active')->where('deleted_at IS NULL',null,false)->orderBy('last_name')->get()->getResultArray();
        $taxRates=$db->table('tax_rates')->where('company_id',$cid)->where('active',1)->get()->getResultArray();
        $quoteNext=(int)(model('CompanySettingModel')->getSetting($cid,'numbering','quote_next')??1);
        $quotePrefix=model('CompanySettingModel')->getSetting($cid,'numbering','quote_prefix')??'QUO-';
        $nextNum=$quotePrefix.str_pad($quoteNext,config('Fieldly')->numberPadding,'0',STR_PAD_LEFT);
        $currency=$this->settings['regional']['currency']??'GBP';
        $prefill=['customer_id'=>$this->request->getGet('customer_id')];
        return $this->view('quotes/create', compact('customers','taxRates','nextNum','currency','prefill'));
    }

    public function store()
    {
        if (!$this->can('edit_quotes')) return redirect()->to('/fieldly/public/index.php/quotes')->with('error','Access denied');
        $post=$this->request->getPost();
        $items=$post['items']??[]; $sub=0; $tax=0;
        foreach ($items as &$item) { $lt=round((float)$item['qty']*(float)$item['unit_price']*(1-(float)($item['discount']??0)/100),2); $item['line_total']=$lt; $sub+=$lt; $tax+=round($lt*(float)($item['tax_rate']??20)/100,2); }
        $id=model('QuoteModel')->insert(['company_id'=>$this->companyId,'customer_id'=>(int)$post['customer_id'],'number'=>$this->nextNumber('quote_prefix','quote_next'),'title'=>trim($post['title']??''),'status'=>'draft','valid_until'=>$post['valid_until']?:null,'subtotal'=>round($sub,2),'tax_total'=>round($tax,2),'total'=>round($sub+$tax,2),'notes'=>trim($post['notes']??''),'terms'=>trim($post['terms']??''),'created_by'=>$this->userId]);
        $db=db_connect();
        foreach ($items as $i=>$item) $db->table('quote_items')->insert(['quote_id'=>$id,'description'=>$item['description']??'','qty'=>$item['qty']??1,'unit_price'=>$item['unit_price']??0,'discount'=>$item['discount']??0,'tax_rate'=>$item['tax_rate']??20,'line_total'=>$item['line_total']??0,'sort_order'=>$i]);
        $this->log('quote.created','quote',$id,'Quote created');
        return redirect()->to("/quotes/{$id}")->with('success','Quote created.');
    }

    public function edit(int $id)
    {
        if (!$this->can('edit_quotes')) return redirect()->to('/fieldly/public/index.php/quotes')->with('error','Access denied');
        $q=$this->getQuoteOr404($id); $db=db_connect(); $cid=$this->companyId;
        $q['items']=$db->table('quote_items')->where('quote_id',$id)->orderBy('sort_order')->get()->getResultArray();
        $customers=$db->table('customers')->where('company_id',$cid)->where('status','active')->where('deleted_at IS NULL',null,false)->orderBy('last_name')->get()->getResultArray();
        $taxRates=$db->table('tax_rates')->where('company_id',$cid)->where('active',1)->get()->getResultArray();
        $currency=$this->settings['regional']['currency']??'GBP';
        return $this->view('quotes/edit', compact('q','customers','taxRates','currency'));
    }

    public function update(int $id)
    {
        if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied');
        $q=$this->getQuoteOr404($id); $post=$this->request->getPost();
        $items=$post['items']??[]; $sub=0; $tax=0; $db=db_connect();
        $db->table('quote_items')->where('quote_id',$id)->delete();
        foreach ($items as $i=>$item) { $lt=round((float)$item['qty']*(float)$item['unit_price']*(1-(float)($item['discount']??0)/100),2); $sub+=$lt; $tax+=round($lt*(float)($item['tax_rate']??20)/100,2); $db->table('quote_items')->insert(['quote_id'=>$id,'description'=>$item['description']??'','qty'=>$item['qty']??1,'unit_price'=>$item['unit_price']??0,'discount'=>$item['discount']??0,'tax_rate'=>$item['tax_rate']??20,'line_total'=>$lt,'sort_order'=>$i]); }
        model('QuoteModel')->update($id,['customer_id'=>(int)$post['customer_id'],'title'=>trim($post['title']??''),'status'=>$post['status']??$q['status'],'valid_until'=>$post['valid_until']?:null,'subtotal'=>round($sub,2),'tax_total'=>round($tax,2),'total'=>round($sub+$tax,2),'notes'=>trim($post['notes']??''),'terms'=>trim($post['terms']??'')]);
        return redirect()->to("/quotes/{$id}")->with('success','Quote updated.');
    }

    public function delete(int $id)   { if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied'); $q=$this->getQuoteOr404($id); $this->softDelete('QuoteModel',$id,'quote',"{$q['number']} – {$q['title']}"); return redirect()->to('/fieldly/public/index.php/quotes')->with('success','Quote moved to recycle bin.'); }
    public function restore(int $id)  { if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied'); $item=model('DeletedItemModel')->where('company_id',$this->companyId)->where('entity_type','quote')->where('entity_id',$id)->where('purged_at IS NULL',null,false)->first(); if (!$item) return redirect()->back()->with('error','Not found.'); $snap=json_decode($item['snapshot_json'],true); unset($snap['deleted_at']); model('QuoteModel')->insert($snap); model('DeletedItemModel')->update($item['id'],['restored_at'=>date('Y-m-d H:i:s'),'restored_by'=>$this->userId]); return redirect()->to("/quotes/{$id}")->with('success','Quote restored.'); }
    public function send(int $id)     { if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied'); $q=$this->getQuoteOr404($id); model('QuoteModel')->update($id,['status'=>'sent','sent_at'=>date('Y-m-d H:i:s')]); $this->log('quote.sent','quote',$id,"Quote {$q['number']} sent"); return redirect()->to("/quotes/{$id}")->with('success','Quote marked as sent.'); }
    public function accept(int $id)   { if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied'); model('QuoteModel')->update($id,['status'=>'accepted','accepted_at'=>date('Y-m-d H:i:s')]); return redirect()->to("/quotes/{$id}")->with('success','Quote accepted.'); }
    public function decline(int $id)  { if (!$this->can('edit_quotes')) return redirect()->back()->with('error','Access denied'); model('QuoteModel')->update($id,['status'=>'declined','declined_at'=>date('Y-m-d H:i:s')]); return redirect()->to("/quotes/{$id}")->with('success','Quote declined.'); }
    public function pdf(int $id)      { return redirect()->to("/quotes/{$id}")->with('error','PDF coming soon.'); }

    public function convertToJob(int $id)
    {
        if (!$this->can('edit_jobs')) return redirect()->back()->with('error','Access denied');
        $q=$this->getQuoteOr404($id); $db=db_connect();
        $defaultStatus=$db->table('job_statuses')->where('company_id',$this->companyId)->where('is_default',1)->get()->getRowArray();
        $jobId=model('JobModel')->insert(['company_id'=>$this->companyId,'customer_id'=>$q['customer_id'],'source_quote_id'=>$id,'status_id'=>$defaultStatus['id']??null,'number'=>$this->nextNumber('job_prefix','job_next'),'title'=>$q['title'],'description'=>$q['notes']??'','source'=>'quote','created_by'=>$this->userId]);
        model('QuoteModel')->update($id,['job_id'=>$jobId]);
        $this->log('quote.converted_job','quote',$id,"Quote {$q['number']} converted to job");
        return redirect()->to("/jobs/{$jobId}")->with('success','Job created from quote.');
    }

    public function convertToInvoice(int $id)
    {
        if (!$this->can('edit_invoices')) return redirect()->back()->with('error','Access denied');
        $q=$this->getQuoteOr404($id); $db=db_connect(); $cid=$this->companyId;
        if ($q['job_id']) { $existing=$db->table('invoices')->where('company_id',$cid)->where('job_id',$q['job_id'])->where('deleted_at IS NULL',null,false)->where('status !=','void')->get()->getRowArray(); if ($existing) return redirect()->back()->with('error',"Invoice {$existing['number']} already exists for the linked job."); }
        return redirect()->to("/invoices/from-job/{$q['job_id']}")->with('success','Creating invoice from quote...');
    }

    private function getQuoteOr404(int $id): array
    {
        $q=model('QuoteModel')->find($id);
        if (!$q||(int)$q['company_id']!==$this->companyId) throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        return $q;
    }
}
