<?php

namespace App\Services\Barobill;

use App\Models\Barobill\HometaxInvoice;
use App\Models\Barobill\HometaxInvoiceJournal;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 홈택스 세금계산서 동기화 서비스
 */
class HometaxSyncService
{
    /**
     * API 응답 데이터를 로컬 DB에 동기화
     *
     * @param  array  $invoices  API에서 받은 세금계산서 목록
     * @param  int  $tenantId  테넌트 ID
     * @param  string  $invoiceType  'sales' 또는 'purchase'
     * @return array 동기화 결과 ['inserted' => int, 'updated' => int, 'failed' => int]
     */
    public function syncInvoices(array $invoices, int $tenantId, string $invoiceType): array
    {
        $result = [
            'inserted' => 0,
            'updated' => 0,
            'failed' => 0,
            'total' => count($invoices),
        ];

        if (empty($invoices)) {
            return $result;
        }

        DB::beginTransaction();

        try {
            foreach ($invoices as $apiData) {
                // 국세청승인번호가 없으면 스킵
                if (empty($apiData['ntsConfirmNum'])) {
                    $result['failed']++;

                    continue;
                }

                $modelData = HometaxInvoice::fromApiData($apiData, $tenantId, $invoiceType);

                // upsert (있으면 업데이트, 없으면 삽입)
                $existing = HometaxInvoice::where('tenant_id', $tenantId)
                    ->where('nts_confirm_num', $modelData['nts_confirm_num'])
                    ->where('invoice_type', $invoiceType)
                    ->first();

                if ($existing) {
                    // 기존 데이터 업데이트 (자체 관리 필드는 유지)
                    $existing->update([
                        'write_date' => $modelData['write_date'],
                        'issue_date' => $modelData['issue_date'],
                        'invoicer_corp_num' => $modelData['invoicer_corp_num'],
                        'invoicer_corp_name' => $modelData['invoicer_corp_name'],
                        'invoicer_ceo_name' => $modelData['invoicer_ceo_name'],
                        'invoicee_corp_num' => $modelData['invoicee_corp_num'],
                        'invoicee_corp_name' => $modelData['invoicee_corp_name'],
                        'invoicee_ceo_name' => $modelData['invoicee_ceo_name'],
                        'supply_amount' => $modelData['supply_amount'],
                        'tax_amount' => $modelData['tax_amount'],
                        'total_amount' => $modelData['total_amount'],
                        'tax_type' => $modelData['tax_type'],
                        'purpose_type' => $modelData['purpose_type'],
                        'item_name' => $modelData['item_name'],
                        'remark' => $modelData['remark'],
                        'synced_at' => now(),
                    ]);
                    $result['updated']++;
                } else {
                    // 새 데이터 삽입
                    HometaxInvoice::create($modelData);
                    $result['inserted']++;
                }
            }

            DB::commit();

            Log::info('[HometaxSync] 동기화 완료', [
                'tenant_id' => $tenantId,
                'invoice_type' => $invoiceType,
                'result' => $result,
            ]);

        } catch (\Throwable $e) {
            DB::rollBack();
            Log::error('[HometaxSync] 동기화 실패', [
                'tenant_id' => $tenantId,
                'invoice_type' => $invoiceType,
                'error' => $e->getMessage(),
            ]);
            throw $e;
        }

        return $result;
    }

    /**
     * 로컬 DB에서 세금계산서 목록 조회
     *
     * @param  int  $tenantId  테넌트 ID
     * @param  string  $invoiceType  'sales' 또는 'purchase'
     * @param  string  $startDate  시작일 (Y-m-d)
     * @param  string  $endDate  종료일 (Y-m-d)
     * @param  string  $dateType  날짜 타입 ('write', 'issue', 'send')
     * @param  string|null  $searchCorp  거래처 검색어
     */
    public function getLocalInvoices(
        int $tenantId,
        string $invoiceType,
        string $startDate,
        string $endDate,
        string $dateType = 'write',
        ?string $searchCorp = null
    ): array {
        $query = HometaxInvoice::where('tenant_id', $tenantId)
            ->where('invoice_type', $invoiceType)
            ->period($startDate, $endDate, $dateType);

        if (! empty($searchCorp)) {
            $query->searchCorp($searchCorp, $invoiceType);
        }

        $invoices = $query->orderByDesc('write_date')->get();

        // 분개 완료 인보이스 ID 조회
        $invoiceIds = $invoices->pluck('id')->toArray();
        $journaledIds = HometaxInvoiceJournal::getJournaledInvoiceIds($tenantId, $invoiceIds);

        // API 응답 형식에 맞게 변환
        $formattedInvoices = $invoices->map(function ($inv) use ($journaledIds) {
            return [
                'id' => $inv->id,
                'ntsConfirmNum' => $inv->nts_confirm_num,
                'writeDate' => $inv->write_date?->format('Ymd'),
                'writeDateFormatted' => $inv->write_date?->format('Y-m-d'),
                'issueDT' => $inv->issue_date?->format('Ymd'),
                'issueDateFormatted' => $inv->issue_date?->format('Y-m-d'),
                'invoicerCorpNum' => $inv->invoicer_corp_num,
                'invoicerCorpName' => $inv->invoicer_corp_name,
                'invoicerCEOName' => $inv->invoicer_ceo_name,
                'invoiceeCorpNum' => $inv->invoicee_corp_num,
                'invoiceeCorpName' => $inv->invoicee_corp_name,
                'invoiceeCEOName' => $inv->invoicee_ceo_name,
                'supplyAmount' => $inv->supply_amount,
                'supplyAmountFormatted' => $inv->formatted_supply_amount,
                'taxAmount' => $inv->tax_amount,
                'taxAmountFormatted' => $inv->formatted_tax_amount,
                'totalAmount' => $inv->total_amount,
                'totalAmountFormatted' => $inv->formatted_total_amount,
                'taxType' => $inv->tax_type,
                'taxTypeName' => $inv->tax_type_name,
                'purposeType' => $inv->purpose_type,
                'purposeTypeName' => $inv->purpose_type_name,
                'issueTypeName' => $inv->issue_type_name,
                'itemName' => $inv->item_name,
                'remark' => $inv->remark,
                'memo' => $inv->memo,
                'category' => $inv->category,
                'isChecked' => $inv->is_checked,
                'hasJournal' => in_array($inv->id, $journaledIds),
                'syncedAt' => $inv->synced_at?->format('Y-m-d H:i:s'),
            ];
        })->toArray();

        // 요약 계산
        $summary = [
            'totalAmount' => $invoices->sum('supply_amount'),
            'totalTax' => $invoices->sum('tax_amount'),
            'totalSum' => $invoices->sum('total_amount'),
            'count' => $invoices->count(),
        ];

        return [
            'invoices' => $formattedInvoices,
            'summary' => $summary,
        ];
    }

    /**
     * 마지막 동기화 시간 조회
     */
    public function getLastSyncTime(int $tenantId, string $invoiceType): ?string
    {
        $lastSync = HometaxInvoice::where('tenant_id', $tenantId)
            ->where('invoice_type', $invoiceType)
            ->orderByDesc('synced_at')
            ->value('synced_at');

        return $lastSync?->format('Y-m-d H:i:s');
    }

    /**
     * 메모 업데이트
     */
    public function updateMemo(int $id, int $tenantId, ?string $memo): bool
    {
        return HometaxInvoice::where('id', $id)
            ->where('tenant_id', $tenantId)
            ->update(['memo' => $memo]) > 0;
    }

    /**
     * 확인 여부 토글
     */
    public function toggleChecked(int $id, int $tenantId): bool
    {
        $invoice = HometaxInvoice::where('id', $id)
            ->where('tenant_id', $tenantId)
            ->first();

        if (! $invoice) {
            return false;
        }

        $invoice->is_checked = ! $invoice->is_checked;

        return $invoice->save();
    }

    /**
     * 분류 태그 업데이트
     */
    public function updateCategory(int $id, int $tenantId, ?string $category): bool
    {
        return HometaxInvoice::where('id', $id)
            ->where('tenant_id', $tenantId)
            ->update(['category' => $category]) > 0;
    }
}
