<?php

namespace App\Models;

use CodeIgniter\Model;

class TransactionModel extends Model
{
    protected $table = 'transactions';
    protected $primaryKey = 'id';
    protected $allowedFields = ['customer', 'cashier', 'barber', 'member_id', 'total', 'discount_amount', 'reward_name', 'payment_method', 'amount_paid', 'items', 'created_at'];
    protected $useTimestamps = false;

    public function getFilteredTransactions(array $filters = []): array
    {
        $builder = $this->builder();

        if (!empty($filters['date_from'])) {
            $builder->where('created_at >=', $filters['date_from'] . ' 00:00:00');
        }
        if (!empty($filters['date_to'])) {
            $builder->where('created_at <=', $filters['date_to'] . ' 23:59:59');
        }
        if (!empty($filters['barber'])) {
            $builder->where('barber', $filters['barber']);
        }
        if (!empty($filters['payment_method'])) {
            $builder->where('payment_method', $filters['payment_method']);
        }

        return $builder->orderBy('id', 'DESC')->get()->getResultArray();
    }

    public function countPromoUsageToday(): int
    {
        $today = date('Y-m-d');
        return $this->where('created_at >=', $today . ' 00:00:00')
            ->where('created_at <=', $today . ' 23:59:59')
            ->where('reward_name IS NOT NULL', null, false)
            ->where('reward_name !=', '')
            ->countAllResults();
    }

    public function getHourlySalesToday(): array
    {
        return $this->getHourlySales(date('Y-m-d'));
    }

    public function getHourlySales(string $date): array
    {
        $builder = $this->builder();
        $builder->select('created_at, total');
        $builder->where('created_at >=', $date . ' 00:00:00');
        $builder->where('created_at <=', $date . ' 23:59:59');
        $records = $builder->get()->getResultArray();

        $labels = [];
        for ($hour = 0; $hour < 24; $hour++) {
            $labels[] = str_pad((string) $hour, 2, '0', STR_PAD_LEFT) . ':00';
        }

        $counts = array_fill(0, 24, 0);
        $totals = array_fill(0, 24, 0);

        foreach ($records as $record) {
            $createdAt = $record['created_at'] ?? '';
            if ($createdAt === '') {
                continue;
            }
            $hour = (int) date('G', strtotime($createdAt));
            $counts[$hour]++;
            $totals[$hour] += (int) ($record['total'] ?? 0);
        }

        $busiestHour = null;
        $maxCount = 0;
        foreach ($counts as $hour => $count) {
            if ($count > $maxCount) {
                $maxCount = $count;
                $busiestHour = $hour;
            }
        }

        return [
            'labels' => $labels,
            'counts' => $counts,
            'totals' => $totals,
            'busiestLabel' => $busiestHour !== null ? $labels[$busiestHour] : null,
            'busiestCount' => $maxCount,
        ];
    }

    public function getSalesSeries(string $range = 'weekly', string $barber = ''): array
    {
        $builder = $this->builder();
        if ($barber !== '') {
            $builder->where('barber', $barber);
        }

        $records = $builder->orderBy('created_at', 'ASC')->get()->getResultArray();
        $labels = [];
        $data = [];

        if ($range === 'monthly') {
            $start = new \DateTime('first day of this month');
            for ($i = 5; $i >= 0; $i--) {
                $month = (clone $start)->modify('-' . $i . ' month');
                $labels[] = $month->format('M Y');
                $data[] = 0;
            }
            foreach ($records as $record) {
                $createdAt = $record['created_at'] ?? '';
                if ($createdAt === '') {
                    continue;
                }
                $monthKey = date('M Y', strtotime($createdAt));
                $index = array_search($monthKey, $labels, true);
                if ($index !== false) {
                    $data[$index] += (int) ($record['total'] ?? 0);
                }
            }
        } elseif ($range === 'yearly') {
            $labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
            $data = array_fill(0, 12, 0);
            foreach ($records as $record) {
                $createdAt = $record['created_at'] ?? '';
                if ($createdAt === '') {
                    continue;
                }
                $month = (int) date('m', strtotime($createdAt));
                $data[$month - 1] += (int) ($record['total'] ?? 0);
            }
        } else {
            for ($i = 6; $i >= 0; $i--) {
                $day = date('Y-m-d', strtotime('-' . $i . ' days'));
                $labels[] = date('d', strtotime($day));
                $data[] = 0;
            }
            foreach ($records as $record) {
                $createdAt = $record['created_at'] ?? '';
                if ($createdAt === '') {
                    continue;
                }
                $dayKey = date('Y-m-d', strtotime($createdAt));
                $index = array_search($dayKey, array_map(static function ($label) {
                    return date('Y-m-d', strtotime('-' . (6 - (int) $label) . ' days'));
                }, $labels), true);
                if ($index !== false) {
                    $data[$index] += (int) ($record['total'] ?? 0);
                }
            }
        }

        return ['labels' => $labels, 'data' => $data];
    }
}
