<?php

namespace Kylin\LawCase\Services;

use Kylin\LawCase\Models\Client;
use Illuminate\Support\Facades\DB;

/**
 * 客户服务
 *
 * 律所客户管理服务，负责客户创建、更新及冲突检索。
 */
class ClientService
{
    public function __construct(
        private ConflictCheckService $conflictCheckService
    ) {}

    public function createClient(array $data): Client
    {
        return DB::transaction(function () use ($data) {
            $data['client_no'] = $this->generateClientNo();

            $client = Client::create($data);

            $this->audit('client_created', $client, ['client_no' => $client->client_no]);

            return $client;
        });
    }

    public function getClientDetail(int $clientId): array
    {
        $client = Client::findOrFail($clientId);

        return [
            'client' => $client,
            'cases' => $client->cases()->with(['principalLawyer', 'milestones'])->get(),
            'documents_count' => $client->cases()->withCount('documents')->get()->sum('documents_count'),
            'total_fees' => $client->cases()->withSum('fees', 'amount')->get()->sum('fees_sum_amount'),
            'total_paid' => $client->cases()->withSum('fees', 'paid_amount')->get()->sum('fees_sum_paid_amount'),
            'conflict_checks' => $client->conflictChecks()->latest()->get(),
        ];
    }

    /**
     * 利益冲突检索 - 按客户名称/证件号搜索
     */
    public function searchConflict(string $keyword): array
    {
        return $this->conflictCheckService->quickSearch($keyword);
    }

    public function updateClient(int $clientId, array $data): Client
    {
        $client = Client::findOrFail($clientId);
        $client->update($data);

        $this->audit('client_updated', $client, ['client_no' => $client->client_no]);

        return $client->fresh();
    }

    public function deleteClient(int $clientId): bool
    {
        $client = Client::findOrFail($clientId);

        $this->audit('client_deleted', $client, ['client_no' => $client->client_no]);

        return $client->delete();
    }

    private function generateClientNo(): string
    {
        $date = now()->format('Ymd');
        $lastClient = Client::whereDate('created_at', today())
            ->orderByDesc('id')
            ->first();
        $sequence = $lastClient ? (intval(substr($lastClient->client_no, -4)) + 1) : 1;

        return sprintf('CLI-%s-%04d', $date, $sequence);
    }

    /**
     * 记录客户审计日志
     *
     * 依据《律师法》和《个人信息保护法》，
     * 客户信息变更需记录审计日志。
     */
    private function audit(string $event, Client $client, array $extra = []): void
    {
        if (! class_exists(\Kylin\AuditLog\Models\AuditLog::class)) {
            return;
        }

        try {
            \Kylin\AuditLog\Models\AuditLog::create([
                'event' => $event,
                'model_type' => Client::class,
                'model_id' => $client->id,
                'new_values' => $extra,
                'old_values' => null,
                'user_id' => auth()->id(),
                'ip' => request()?->ip(),
                'url' => request()?->fullUrl(),
                'tag' => 'law-case-client',
            ]);
        } catch (\Throwable $e) {
            logger()->warning('客户审计日志写入失败', [
                'error' => $e->getMessage(),
                'client_id' => $client->id,
                'event' => $event,
            ]);
        }
    }
}
