<?php

namespace App\Services;

use App\Enums\CampaignStatus;
use App\Repositories\CampaignRepository;
use App\Repositories\CampaignBriefRepository;
use App\Support\IdFormatter;
use App\Support\Uuid;
use App\Utils\AuditLog;
use Illuminate\Support\Str;

class CampaignService extends BaseService
{
    protected $repository;
    protected $briefRepository;

    public function __construct()
    {
        $this->repository = new CampaignRepository();
        $this->briefRepository = new CampaignBriefRepository();
    }

    public function getListWithPaginate(?string $orgHex, int $perPage = 15)
    {
        return $this->repository->paginateByOrganization($orgHex, $perPage);
    }

    public function getListForTable(?string $orgHex, array $filters = [], int $perPage = 10)
    {
        return $this->repository->paginateFilteredByOrganization($orgHex, $filters, $perPage);
    }

    public function createCampaign(array $data, ?string $orgHex)
    {
        $data = $this->prepareCreateData($data, $orgHex, ['assigned_to_id']);

        if (array_key_exists('assigned_to_id', $data) && $data['assigned_to_id'] === '') {
            $data['assigned_to_id'] = null;
        }

        if (!isset($data['status'])) {
            $data['status'] = CampaignStatus::default()->value;
        }

        $campaign = $this->repository->create($data);

        $details = 'Tên: ' . ($campaign->campaign_name ?? 'Unknown');
        if (!empty($campaign->product_name)) {
            $details .= ', Sản phẩm: ' . $campaign->product_name;
        }
        if (!empty($campaign->assigned_to_id)) {
            $assigned = $campaign->assignedTo;
            $details .= ', Người phụ trách: ' . ($assigned->display_name ?? $assigned->name ?? 'Unknown');
        }
        AuditLog::log('create_campaign', 'campaign', IdFormatter::formatModelId($campaign), $campaign->campaign_name ?? 'Unknown', $details, 'campaigns');

        return $campaign;
    }

    public function updateCampaign(string $id, array $data, ?string $orgHex)
    {
        if (!empty($data['assigned_to_id'])) {
            $bin = IdFormatter::hexToBinary($data['assigned_to_id']);
            if ($bin) {
                $data['assigned_to_id'] = $bin;
            }
        } elseif (array_key_exists('assigned_to_id', $data) && $data['assigned_to_id'] === '') {
            $data['assigned_to_id'] = null;
        }

        $old = $this->repository->getByIdInOrganization($id, $orgHex);
        if (!$old) {
            return false;
        }

        $updated = $this->repository->updateInOrganization($id, $data, $orgHex);

        if ($updated) {
            $fieldLabels = [
                'campaign_name' => 'Tên chiến dịch', 'product_name' => 'Sản phẩm',
                'assigned_to_id' => 'Người phụ trách', 'status' => 'Trạng thái',
                'start_date' => 'Ngày bắt đầu', 'end_date' => 'Ngày kết thúc',
                'description' => 'Mô tả', 'notes' => 'Ghi chú',
            ];
            $details = $this->buildAuditDiff($data, $old, $fieldLabels);
            if (trim($details)) {
                AuditLog::log('update_campaign', 'campaign', IdFormatter::formatModelId($old), $old->campaign_name ?? 'Unknown', trim($details), 'campaigns');
            }
        }

        return $updated;
    }

    public function updateCampaignBrief(string $campaignId, array $data, ?string $orgHex)
    {
        $campaign = $this->repository->getByIdInOrganization($campaignId, $orgHex);
        if (!$campaign) {
            return null;
        }

        $brief = $this->briefRepository->getByCampaignId($campaignId);
        if ($brief) {
            return $this->briefRepository->update($brief->id, $data);
        }

        $data['id'] = Uuid::uuid7Binary();
        $data['campaign_id'] = IdFormatter::hexToBinary($campaignId) ?? $campaignId;
        return $this->briefRepository->create($data);
    }

    public function deleteCampaign(string $id, ?string $orgHex)
    {
        $campaign = $this->repository->getByIdInOrganization($id, $orgHex);
        if (!$campaign) {
            return false;
        }

        $campaignName = $campaign->campaign_name ?? 'Unknown';
        $campaignHexId = IdFormatter::formatModelId($campaign);

        $this->briefRepository->deleteByCampaignId($id);
        $deleted = $this->repository->deleteInOrganization($id, $orgHex);

        if ($deleted) {
            AuditLog::log('delete_campaign', 'campaign', $campaignHexId, $campaignName, 'Đã xóa chiến dịch: ' . $campaignName, 'campaigns');
        }

        return $deleted;
    }

    public function deleteCampaignBrief(string $campaignId, ?string $orgHex)
    {
        $campaign = $this->repository->getByIdInOrganization($campaignId, $orgHex);
        if (!$campaign) {
            return false;
        }

        $brief = $this->briefRepository->getByCampaignId($campaignId);
        if ($brief && $brief->product_image_url) {
            $this->deleteBriefImage($brief->product_image_url);
        }

        $this->briefRepository->deleteByCampaignId($campaignId);
        return true;
    }

    public function uploadBriefImage($file, string $campaignId): string
    {
        $extension = $file->getClientOriginalExtension();
        $filename = Str::random(40) . '.' . $extension;
        $relativePath = 'uploads/briefs/';
        $file->move(public_path($relativePath), $filename);
        return '/' . $relativePath . $filename;
    }

    public function deleteBriefImage(string $imageUrl): void
    {
        $path = public_path(ltrim($imageUrl, '/'));
        if (file_exists($path)) {
            unlink($path);
        }
    }

    public function getCampaignById(string $id, ?string $orgHex)
    {
        return $this->repository->getByIdInOrganization($id, $orgHex);
    }

    public function getCampaignWithBrief(string $id, ?string $orgHex)
    {
        return $this->repository->getWithBriefInOrganization($id, $orgHex);
    }

    public function getCampaignWithBookings(string $id, ?string $orgHex)
    {
        return $this->repository->getWithBookingsInOrganization($id, $orgHex);
    }

    /**
     * [TỐI ƯU] Phiên bản nhẹ: không load bookingNotes.user, thêm booking_notes_count
     */
    public function getCampaignWithBookingsLight(string $id, ?string $orgHex)
    {
        return $this->repository->getWithBookingsLight($id, $orgHex);
    }

    public function searchCampaignByName(string $name, ?string $orgHex)
    {
        return $this->repository->searchByName($name, $orgHex);
    }
}
