<?php

namespace App\Services;

use App\Support\AnalysisResultCache;
use App\Support\ExcelStreamReader;
use Illuminate\Support\Facades\Storage;
use PhpOffice\PhpSpreadsheet\Shared\Date;

class AnalysisService
{
    private const UPLOAD_DIR = 'private_uploads';

    /**
     * Số cột dữ liệu tối đa của file đơn hàng liên kết.
     * Mẫu file hiện tại dùng đến cột AG (33); dành dư cho biến thể khác.
     */
    private const DATA_COL_COUNT = 40;

    public function storeUpload($file)
    {
        $filename = 'analysis_' . time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
        $path = $file->storeAs(self::UPLOAD_DIR, $filename, 'local');
        return $path;
    }

    /**
     * Xử lý file đã upload: parse (stream) → phân tích → ghi cache theo hash
     * nội dung file. Nếu cùng nội dung đã xử lý trước đó, trả luôn kết quả cache.
     *
     * @return array|null kết quả dùng cho controller (headers/preview/total_rows/sheet_name/affiliate_metrics)
     */
    public function processFile($filePath)
    {
        $fullPath = Storage::disk('local')->path($filePath);
        $cached = AnalysisResultCache::get('analysis', $fullPath);
        if ($cached !== null) {
            return $cached;
        }

        $parsed = $this->parseExcel($filePath);

        $metrics = $this->analyzeAffiliateOrders($parsed);
        $result = [
            'headers' => $parsed['headers'],
            'preview' => $metrics['preview'] ?? [],
            'total_rows' => $metrics['total_orders'] ?? 0,
            'sheet_name' => $parsed['sheet_name'],
            'affiliate_metrics' => $metrics,
        ];

        AnalysisResultCache::put('analysis', $fullPath, $result);

        return $result;
    }

    /**
     * Đọc file Excel đơn hàng liên kết theo dòng bằng stream
     * (ReadFilter + readDataOnly) để không load toàn bộ workbook vào RAM.
     * Dòng 1 = tiêu đề cột; data trả về là Generator và chỉ chạy 1 lần.
     */
    public function parseExcel($filePath)
    {
        $fullPath = Storage::disk('local')->path($filePath);
        if (!file_exists($fullPath)) {
            throw new \Exception('File không tồn tại.');
        }

        [$spreadsheet, $worksheet] = ExcelStreamReader::open($fullPath, self::DATA_COL_COUNT);
        $sheetName = $worksheet->getTitle();

        // Dòng 1: tiêu đề cột (giữ nguyên thứ tự, kể cả cột trống gần cuối)
        $headerRow = ExcelStreamReader::firstRow($worksheet, self::DATA_COL_COUNT);
        $headers = array_map(function ($h) {
            return trim((string) $h);
        }, $headerRow);
        $colCount = count($headers);

        // Dữ liệu từ dòng 2: generator, chỉ chạy khi được duyệt
        $data = (function () use ($worksheet, $headers, $colCount) {
            foreach (ExcelStreamReader::rows($worksheet, self::DATA_COL_COUNT, 2) as $rowData) {
                $rowData = array_pad($rowData, $colCount, null);
                $item = [];
                for ($i = 0; $i < $colCount; $i++) {
                    $header = $headers[$i];
                    $value = $rowData[$i] ?? null;
                    if (is_numeric($value) && $value !== '' && !preg_match('/^(mã|id)/i', $header) && $header !== 'code') {
                        $value = is_float($value + 0) ? (float) $value : (int) $value;
                    }
                    $item[$header] = $value;
                }
                yield $item;
            }
        })();

        return [
            'headers' => $headers,
            'data' => $data,
            'sheet_name' => $sheetName,
        ];
    }

    /**
     * Phát hiện cột affiliate từ headers — chạy 1 lần, O(m)
     * @return array{hCreator: ?string, hOrderId: ?string, hProductId: ?string, hProductName: ?string, hQty: ?string, hPayment: ?string, hStdEst: ?string, hStdAct: ?string, hAdEst: ?string, hAdAct: ?string, hCreatedAt: ?string, hContentType: ?string, hStatus: ?string, hCommissionBaseEst: ?string, hCommissionBaseAct: ?string}
     */
    private static function detectAffiliateColumns(array $headers): array
    {
        $map = [
            'hCreator' => 'Tên người dùng nhà sáng tạo',
            'hOrderId' => 'ID đơn hàng',
            'hProductId' => 'ID sản phẩm',
            'hProductName' => 'Tên sản phẩm',
            'hQty' => 'Số lượng',
            'hPayment' => 'Payment Amount',
            'hStdEst' => 'Thanh toán hoa hồng tiêu chuẩn ước tính',
            'hStdAct' => ['Thanh toán hoa hồng thực tế', 'Quảng cáo'],
            'hAdEst' => 'Thanh toán hoa hồng Quảng cáo cửa hàng ước tính',
            'hAdAct' => 'Thanh toán hoa hồng Quảng cáo cửa hàng thực tế',
            'hCreatedAt' => 'Thời gian đã tạo',
            'hContentType' => 'Loại nội dung',
            'hStatus' => 'Trạng thái đơn hàng',
            'hCommissionBaseEst' => 'Cơ sở hoa hồng ước tính',
            'hCommissionBaseAct' => 'Cơ sở hoa hồng thực tế',
        ];

        $result = array_fill_keys(array_keys($map), null);

        foreach ($headers as $h) {
            $h = trim($h);
            // Ưu tiên khớp chính xác trước
            foreach ($map as $key => $search) {
                if ($result[$key] !== null) continue;
                if (is_array($search)) {
                    // exclude check: chứa keyword đầu nhưng không chứa keyword loại trừ
                    if (str_contains($h, $search[0]) && !str_contains($h, $search[1])) {
                        $result[$key] = $h;
                    }
                } elseif ($h === $search) {
                    $result[$key] = $h;
                } elseif (str_contains($h, $search)) {
                    $result[$key] = $h;
                }
            }
        }

        return $result;
    }

    /**
     * Phân tích đơn hàng affiliate — single pass O(n), gộp toàn bộ metric trong 1 lần duyệt
     */
    public function analyzeAffiliateOrders($parsed)
    {
        $data = $parsed['data'];
        $rowCount = 0;

        $col = self::detectAffiliateColumns($parsed['headers']);

        if (!$col['hCreator'] || !$col['hOrderId']) {
            return null;
        }

        // ─── Single pass: tính mọi thống kê ───
        $orderDetails = [];
        $previewRows = [];
        $uniqueCreators = [];
        $uniqueProductIds = [];
        $creatorStats = [];
        $productStats = [];
        $creatorStatsByProduct = [];
        $contentTypeStats = [];
        $statusStats = [];
        $dailyStats = [];
        $contentTypeOptions = [];
        $statusOptions = [];

        $totalQty = 0;
        $totalRevenue = 0;
        $stdRevenue = 0;
        $adRevenue = 0;
        $stdActSum = 0;
        $adActSum = 0;
        $stdEstSum = 0;
        $adEstSum = 0;
        $adOrderCount = 0;

        foreach ($data as $row) {
            if (count($previewRows) < 50) {
                $previewRows[] = $row;
            }

            $creator = $row[$col['hCreator']] ?? null;
            $orderId = $row[$col['hOrderId']] ?? null;
            $productId = $row[$col['hProductId']] ?? null;
            $qtyRaw = $row[$col['hQty']] ?? 0;
            $paymentRaw = $row[$col['hPayment']] ?? 0;
            $stdActRaw = $row[$col['hStdAct']] ?? null;
            $adActRaw = $row[$col['hAdAct']] ?? null;
            $stdEstRaw = $row[$col['hStdEst']] ?? null;
            $adEstRaw = $row[$col['hAdEst']] ?? null;

            // Chuẩn hoá giá trị số — 1 lần duy nhất
            $paymentVal = is_numeric($paymentRaw) ? (float) $paymentRaw : 0;
            $qtyVal = is_numeric($qtyRaw) ? (int) $qtyRaw : 0;
            $stdActVal = is_numeric($stdActRaw) ? (float) $stdActRaw : 0;
            $adActVal = is_numeric($adActRaw) ? (float) $adActRaw : 0;
            $stdEstVal = is_numeric($stdEstRaw) ? (float) $stdEstRaw : 0;
            $adEstVal = is_numeric($adEstRaw) ? (float) $adEstRaw : 0;

            // Product key chuẩn hoá
            $productKey = '';
            if ($productId !== null && $productId !== '') {
                $productKey = is_float($productId) ? sprintf('%.0f', $productId) : (string) $productId;
            }

            // Hash set thay array_unique
            if ($creator) $uniqueCreators[$creator] = true;
            if ($productKey !== '') $uniqueProductIds[$productKey] = true;

            // Tổng hợp cấp cao
            $totalQty += $qtyVal;
            $totalRevenue += $paymentVal;
            $stdActSum += $stdActVal;
            $adActSum += $adActVal;
            $stdEstSum += $stdEstVal;
            $adEstSum += $adEstVal;

            $isAd = $adEstRaw !== null && $adEstRaw !== '' && is_numeric($adEstRaw);
            if ($isAd) {
                $adOrderCount++;
                $adRevenue += $paymentVal;
            } else {
                $stdRevenue += $paymentVal;
            }

            // Thống kê theo sản phẩm
            if ($productKey !== '') {
                if (!isset($productStats[$productKey])) {
                    $productName = ($col['hProductName'] && isset($row[$col['hProductName']]))
                        ? $row[$col['hProductName']]
                        : $productKey;
                    $productStats[$productKey] = [
                        'name' => $productName,
                        'orders' => 0, 'revenue' => 0,
                        'std_act' => 0, 'ad_act' => 0,
                        'std_est' => 0, 'ad_est' => 0,
                    ];
                }
                $ps = &$productStats[$productKey];
                $ps['orders']++;
                $ps['revenue'] += $paymentVal;
                $ps['std_est'] += $stdEstVal;
                $ps['ad_est'] += $adEstVal;
                $ps['std_act'] += $stdActVal;
                $ps['ad_act'] += $adActVal;
                unset($ps);
            }

            // Thống kê theo creator — và creator-by-product (gộp trong 1 pass)
            if ($creator) {
                if (!isset($creatorStats[$creator])) {
                    $creatorStats[$creator] = [
                        'orders' => 0, 'revenue' => 0,
                        'std_act' => 0, 'ad_act' => 0,
                        'std_est' => 0, 'ad_est' => 0,
                    ];
                }
                $cs = &$creatorStats[$creator];
                $cs['orders']++;
                $cs['revenue'] += $paymentVal;
                $cs['std_est'] += $stdEstVal;
                $cs['ad_est'] += $adEstVal;
                $cs['std_act'] += $stdActVal;
                $cs['ad_act'] += $adActVal;
                unset($cs);

                // Creator-by-product (gộp luôn vào main loop, tránh quét orderDetails lần 2)
                if ($productKey !== '') {
                    if (!isset($creatorStatsByProduct[$productKey])) {
                        $creatorStatsByProduct[$productKey] = [];
                    }
                    if (!isset($creatorStatsByProduct[$productKey][$creator])) {
                        $creatorStatsByProduct[$productKey][$creator] = [
                            'orders' => 0, 'revenue' => 0,
                            'std_est' => 0, 'ad_est' => 0,
                            'std_act' => 0, 'ad_act' => 0,
                        ];
                    }
                    $csp = &$creatorStatsByProduct[$productKey][$creator];
                    $csp['orders']++;
                    $csp['revenue'] += $paymentVal;
                    $csp['std_est'] += $stdEstVal;
                    $csp['ad_est'] += $adEstVal;
                    $csp['std_act'] += $stdActVal;
                    $csp['ad_act'] += $adActVal;
                    unset($csp);
                }
            }

            // Loại nội dung + trạng thái
            $contentVal = $col['hContentType'] && isset($row[$col['hContentType']]) ? (string) $row[$col['hContentType']] : '';
            $statusVal = $col['hStatus'] && isset($row[$col['hStatus']]) ? (string) $row[$col['hStatus']] : '';
            if ($contentVal !== '') $contentTypeOptions[$contentVal] = true;
            if ($statusVal !== '') $statusOptions[$statusVal] = true;

            // Parse ngày — 1 lần, dùng cho cả orderDetails và dailyStats
            $parsedDate = $col['hCreatedAt'] && isset($row[$col['hCreatedAt']])
                ? self::parseDateRaw($row[$col['hCreatedAt']])
                : null;
            $createdAtISO = $parsedDate ? $parsedDate->format('Y-m-d H:i:s') : null;
            $createdAtDisplay = $parsedDate ? $parsedDate->format('j/n/Y g:i:s A') : null;

            // Chi tiết đơn hàng (cho bảng hiển thị)
            $orderDetails[] = [
                'order_id' => (string) $orderId,
                'product_id' => $productKey,
                'created_at' => $createdAtISO,
                'created_at_display' => $createdAtDisplay,
                'creator' => $creator ?? '',
                'content_type' => $contentVal,
                'product_name' => $col['hProductName'] && isset($row[$col['hProductName']]) ? (string) $row[$col['hProductName']] : '',
                'quantity' => $qtyVal,
                'status' => $statusVal,
                'revenue' => $paymentVal,
                'commission_base_est' => $col['hCommissionBaseEst'] && isset($row[$col['hCommissionBaseEst']]) && is_numeric($row[$col['hCommissionBaseEst']]) ? (float) $row[$col['hCommissionBaseEst']] : 0,
                'commission_base_act' => $col['hCommissionBaseAct'] && isset($row[$col['hCommissionBaseAct']]) && is_numeric($row[$col['hCommissionBaseAct']]) ? (float) $row[$col['hCommissionBaseAct']] : 0,
                'std_commission_est' => $stdEstVal,
                'std_commission_act' => $stdActVal,
                'ad_commission_est' => $adEstVal,
                'ad_commission_act' => $adActVal,
                'total_commission_est' => $stdEstVal + $adEstVal,
                'total_commission_act' => $stdActVal + $adActVal,
            ];

            // Thống kê theo loại nội dung
            $ctKey = $contentVal !== '' ? $contentVal : 'Không xác định';
            if (!isset($contentTypeStats[$ctKey])) {
                $contentTypeStats[$ctKey] = ['orders' => 0, 'revenue' => 0, 'std_commission_est' => 0, 'ad_commission_est' => 0, 'std_commission_act' => 0, 'ad_commission_act' => 0];
            }
            $cts = &$contentTypeStats[$ctKey];
            $cts['orders']++;
            $cts['revenue'] += $paymentVal;
            $cts['std_commission_est'] += $stdEstVal;
            $cts['ad_commission_est'] += $adEstVal;
            $cts['std_commission_act'] += $stdActVal;
            $cts['ad_commission_act'] += $adActVal;
            unset($cts);

            // Thống kê theo trạng thái
            $stKey = $statusVal !== '' ? $statusVal : 'Không xác định';
            if (!isset($statusStats[$stKey])) {
                $statusStats[$stKey] = ['orders' => 0, 'revenue' => 0, 'std_commission_est' => 0, 'ad_commission_est' => 0, 'std_commission_act' => 0, 'ad_commission_act' => 0];
            }
            $sts = &$statusStats[$stKey];
            $sts['orders']++;
            $sts['revenue'] += $paymentVal;
            $sts['std_commission_est'] += $stdEstVal;
            $sts['ad_commission_est'] += $adEstVal;
            $sts['std_commission_act'] += $stdActVal;
            $sts['ad_commission_act'] += $adActVal;
            unset($sts);

            // Thống kê theo ngày
            if ($parsedDate) {
                $createdDate = $parsedDate->format('Y-m-d');
                if (!isset($dailyStats[$createdDate])) {
                    $dailyStats[$createdDate] = ['organic_orders' => 0, 'ad_orders' => 0, 'revenue' => 0];
                }
                $ds = &$dailyStats[$createdDate];
                if ($isAd) {
                    $ds['ad_orders']++;
                } else {
                    $ds['organic_orders']++;
                }
                $ds['revenue'] += $paymentVal;
                unset($ds);
            }

            $rowCount++;
        }

        if ($rowCount === 0) {
            return null;
        }

        // ─── Phase 2: Xử lý hậu kỳ (sort, format) — O(k log k) với k << n ───
        $organicOrderCount = $rowCount - $adOrderCount;
        $totalActualCommission = $stdActSum + $adActSum;
        $totalEstimatedCommission = $stdEstSum + $adEstSum;

        // Top creators theo doanh thu
        uasort($creatorStats, fn($a, $b) => $b['revenue'] <=> $a['revenue']);
        $topCreators = [];
        $stt = 0;
        foreach ($creatorStats as $name => $stats) {
            $stt++;
            $totalEst = $stats['std_est'] + $stats['ad_est'];
            $totalAct = $stats['std_act'] + $stats['ad_act'];
            $topCreators[] = [
                'stt' => $stt,
                'name' => $name,
                'orders' => $stats['orders'],
                'revenue' => $stats['revenue'],
                'std_commission_est' => $stats['std_est'],
                'std_commission_act' => $stats['std_act'],
                'ad_commission_est' => $stats['ad_est'],
                'ad_commission_act' => $stats['ad_act'],
                'total_commission_est' => $totalEst,
                'total_commission_act' => $totalAct,
                'commission_ratio_est' => $stats['revenue'] > 0 ? round($totalEst / $stats['revenue'] * 100, 2) : 0,
                'commission_ratio_act' => $stats['revenue'] > 0 ? round($totalAct / $stats['revenue'] * 100, 2) : 0,
                'std_commission_ratio_est' => $stats['revenue'] > 0 ? round($stats['std_est'] / $stats['revenue'] * 100, 2) : 0,
                'ad_commission_ratio_est' => $stats['revenue'] > 0 ? round($stats['ad_est'] / $stats['revenue'] * 100, 2) : 0,
            ];
        }

        // Top sản phẩm theo doanh thu
        uasort($productStats, fn($a, $b) => $b['revenue'] <=> $a['revenue']);
        $topProducts = [];
        $stt = 0;
        foreach ($productStats as $id => $stats) {
            $stt++;
            $totalEst = $stats['std_est'] + $stats['ad_est'];
            $totalAct = $stats['std_act'] + $stats['ad_act'];
            $topProducts[] = [
                'stt' => $stt,
                'product_id' => (string) $id,
                'name' => $stats['name'],
                'orders' => $stats['orders'],
                'revenue' => $stats['revenue'],
                'std_commission_est' => $stats['std_est'],
                'std_commission_act' => $stats['std_act'],
                'ad_commission_est' => $stats['ad_est'],
                'ad_commission_act' => $stats['ad_act'],
                'total_commission_est' => $totalEst,
                'total_commission_act' => $totalAct,
                'commission_ratio_est' => $stats['revenue'] > 0 ? round($totalEst / $stats['revenue'] * 100, 2) : 0,
                'commission_ratio_act' => $stats['revenue'] > 0 ? round($totalAct / $stats['revenue'] * 100, 2) : 0,
                'std_commission_ratio_est' => $stats['revenue'] > 0 ? round($stats['std_est'] / $stats['revenue'] * 100, 2) : 0,
                'ad_commission_ratio_est' => $stats['revenue'] > 0 ? round($stats['ad_est'] / $stats['revenue'] * 100, 2) : 0,
            ];
        }

        // Top creators theo từng sản phẩm (dữ liệu đã được gộp trong main loop)
        $topCreatorsByProduct = [];
        foreach ($creatorStatsByProduct as $pid => $cstats) {
            uasort($cstats, fn($a, $b) => $b['revenue'] <=> $a['revenue']);
            $list = [];
            $stt = 0;
            foreach ($cstats as $name => $s) {
                $stt++;
                $totalEst = $s['std_est'] + $s['ad_est'];
                $totalAct = $s['std_act'] + $s['ad_act'];
                $list[] = [
                    'stt' => $stt,
                    'name' => $name,
                    'orders' => $s['orders'],
                    'revenue' => $s['revenue'],
                    'std_commission_est' => $s['std_est'],
                    'ad_commission_est' => $s['ad_est'],
                    'total_commission_est' => $totalEst,
                    'std_commission_act' => $s['std_act'],
                    'ad_commission_act' => $s['ad_act'],
                    'total_commission_act' => $totalAct,
                    'commission_ratio_est' => $s['revenue'] > 0 ? round($totalEst / $s['revenue'] * 100, 2) : 0,
                    'commission_ratio_act' => $s['revenue'] > 0 ? round($totalAct / $s['revenue'] * 100, 2) : 0,
                    'std_commission_ratio_est' => $s['revenue'] > 0 ? round($s['std_est'] / $s['revenue'] * 100, 2) : 0,
                    'ad_commission_ratio_est' => $s['revenue'] > 0 ? round($s['ad_est'] / $s['revenue'] * 100, 2) : 0,
                ];
            }
            $topCreatorsByProduct[$pid] = $list;
        }

        $commissionRatio = $totalEstimatedCommission > 0
            ? round(($totalActualCommission / $totalEstimatedCommission) * 100, 2)
            : 0;
        $commissionRatioEst = $totalRevenue > 0
            ? round(($totalEstimatedCommission / $totalRevenue) * 100, 2)
            : 0;
        $commissionRatioAct = $totalRevenue > 0
            ? round(($totalActualCommission / $totalRevenue) * 100, 2)
            : 0;
        $stdCommissionRatioEst = $totalRevenue > 0
            ? round(($stdEstSum / $totalRevenue) * 100, 2)
            : 0;
        $adCommissionRatioEst = $totalRevenue > 0
            ? round(($adEstSum / $totalRevenue) * 100, 2)
            : 0;

        return [
            'total_orders' => $rowCount,
            'organic_orders' => $organicOrderCount,
            'ad_orders' => $adOrderCount,
            'unique_creators' => count($uniqueCreators),
            'unique_products' => count($uniqueProductIds),
            'total_quantity' => $totalQty,
            'total_actual_commission' => $totalActualCommission,
            'total_estimated_commission' => $totalEstimatedCommission,
            'std_actual_commission' => $stdActSum,
            'ad_actual_commission' => $adActSum,
            'std_estimated_commission' => $stdEstSum,
            'ad_estimated_commission' => $adEstSum,
            'commission_ratio' => $commissionRatio,
            'commission_ratio_est' => $commissionRatioEst,
            'commission_ratio_act' => $commissionRatioAct,
            'std_commission_ratio_est' => $stdCommissionRatioEst,
            'ad_commission_ratio_est' => $adCommissionRatioEst,
            'total_revenue' => $totalRevenue,
            'std_revenue' => $stdRevenue,
            'ad_revenue' => $adRevenue,
            'order_details' => $orderDetails,
            'order_details_count' => count($orderDetails),
            'preview' => $previewRows,
            'order_filter_content_types' => array_keys($contentTypeOptions),
            'order_filter_statuses' => array_keys($statusOptions),
            'top_creators' => $topCreators,
            'top_creators_count' => count($creatorStats),
            'top_creators_by_product' => $topCreatorsByProduct,
            'top_products' => $topProducts,
            'top_products_count' => count($productStats),
            'content_type_stats' => $contentTypeStats,
            'order_status_stats' => $statusStats,
            'daily_stats' => $dailyStats,
        ];
    }

    /**
     * Parse raw date value từ Excel về DateTime object
     */
    private static function parseDateRaw($raw): ?\DateTimeInterface
    {
        if ($raw instanceof \DateTimeInterface) {
            return $raw;
        }

        if (is_numeric($raw)) {
            try {
                return Date::excelToDateTimeObject((float) $raw);
            } catch (\Exception $e) {
                return null;
            }
        }

        $str = trim((string) $raw);
        if ($str === '') return null;

        if (preg_match('#^(\d{1,2})/(\d{1,2})/(\d{4})\s*(\d{1,2}:\d{2}(?::\d{2})?)?\s*(AM|PM)?$#i', $str, $m)) {
            $day = (int) $m[1];
            $month = (int) $m[2];
            $year = (int) $m[3];
            $time = $m[4] ?? '00:00:00';
            $ampm = $m[5] ?? '';
            $parts = explode(':', $time);
            $h = (int) $parts[0];
            $i = (int) ($parts[1] ?? 0);
            $s = (int) ($parts[2] ?? 0);
            if (strtoupper($ampm) === 'PM' && $h < 12) $h += 12;
            if (strtoupper($ampm) === 'AM' && $h === 12) $h = 0;
            try {
                return new \DateTime(sprintf('%04d-%02d-%02d %02d:%02d:%02d', $year, $month, $day, $h, $i, $s));
            } catch (\Exception $e) {
                return null;
            }
        }

        if (preg_match('#^(\d{4})[-/](\d{1,2})[-/](\d{1,2})(?:\s+(\d{1,2}:\d{2}(?::\d{2})?))?#', $str, $m)) {
            try {
                $time = $m[4] ?? '00:00:00';
                return new \DateTime("{$m[1]}-{$m[2]}-{$m[3]} {$time}");
            } catch (\Exception $e) {
                return null;
            }
        }

        $ts = strtotime($str);
        if ($ts !== false) {
            return (new \DateTime())->setTimestamp($ts);
        }

        return null;
    }

    public function deleteUpload($filePath)
    {
        if ($filePath && Storage::disk('local')->exists($filePath)) {
            Storage::disk('local')->delete($filePath);
        }
    }
}
