<?php

namespace Database\Seeders;

use App\Models\BadDebts\BadDebt;
use App\Models\Orders\Client;
use App\Models\Tenants\Approval;
use App\Models\Tenants\ApprovalForm;
use App\Models\Tenants\ApprovalStep;
use App\Models\Tenants\Deposit;
use App\Models\Tenants\ExpectedExpense;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

/**
 * 종합분석 페이지 테스트 데이터 Seeder
 *
 * 다음 테이블에 샘플 데이터를 생성합니다:
 * - ApprovalForm, Approval (결재 대기)
 * - ExpectedExpense (예상 지출)
 * - Deposit (입금)
 * - BadDebt (채권추심)
 * - Client (미수금/여신한도 업데이트)
 */
class ComprehensiveAnalysisSeeder extends Seeder
{
    private int $tenantId = 287;  // 프론트_테스트회사

    private int $userId = 33;  // 홍킬동 (Tenant 287 기본 사용자)

    public function run(): void
    {
        $this->command->info('종합분석 테스트 데이터 생성 시작...');

        DB::transaction(function () {
            $this->seedApprovalForms();
            $this->seedApprovals();
            $this->seedExpectedExpenses();
            $this->seedDeposits();
            $this->seedBadDebts();
            $this->updateClientBalances();
        });

        $this->command->info('종합분석 테스트 데이터 생성 완료!');
    }

    /**
     * 결재 양식 생성
     */
    private function seedApprovalForms(): void
    {
        $forms = [
            ['code' => 'proposal', 'name' => '품의서', 'category' => 'request'],
            ['code' => 'expenseReport', 'name' => '지출결의서', 'category' => 'expense'],
            ['code' => 'expenseEstimate', 'name' => '지출 예상 내역서', 'category' => 'expense_estimate'],
        ];

        foreach ($forms as $form) {
            ApprovalForm::firstOrCreate(
                ['tenant_id' => $this->tenantId, 'code' => $form['code']],
                [
                    'name' => $form['name'],
                    'category' => $form['category'],
                    'template' => ['fields' => []],
                    'is_active' => true,
                    'created_by' => $this->userId,
                ]
            );
        }

        $this->command->info('  - 결재 양식 3건 생성');
    }

    /**
     * 결재 대기 문서 생성
     */
    private function seedApprovals(): void
    {
        $form = ApprovalForm::where('tenant_id', $this->tenantId)->first();

        if (! $form) {
            $this->command->warn('  - 결재 양식이 없어 결재 문서 생성 건너뜀');

            return;
        }

        $approvals = [
            ['title' => '12월 사무용품 구매 품의', 'time' => '09:15'],
            ['title' => '연말 회식비 지출결의', 'time' => '10:30'],
            ['title' => '출장비 정산 요청', 'time' => '11:45'],
            ['title' => '서버 호스팅 비용 결재', 'time' => '14:20'],
            ['title' => '신규 장비 구매 품의', 'time' => '15:00'],
        ];

        $today = Carbon::today();

        foreach ($approvals as $i => $approval) {
            $approvalRecord = Approval::firstOrCreate(
                [
                    'tenant_id' => $this->tenantId,
                    'document_number' => 'DOC-'.date('Ymd').'-'.str_pad($i + 1, 3, '0', STR_PAD_LEFT),
                ],
                [
                    'form_id' => $form->id,
                    'title' => $approval['title'],
                    'content' => ['description' => $approval['title'].' 내용입니다.'],
                    'status' => Approval::STATUS_PENDING,
                    'drafter_id' => $this->userId,
                    'drafted_at' => $today->copy()->setTimeFromTimeString($approval['time']),
                    'current_step' => 1,
                    'created_by' => $this->userId,
                ]
            );

            // 결재 단계 생성 (현재 로그인 사용자가 승인/반려할 수 있도록)
            ApprovalStep::firstOrCreate(
                [
                    'approval_id' => $approvalRecord->id,
                    'step_order' => 1,
                ],
                [
                    'step_type' => 'approval',  // ApprovalLine::STEP_TYPE_APPROVAL
                    'approver_id' => $this->userId,
                    'status' => ApprovalStep::STATUS_PENDING,
                ]
            );
        }

        $this->command->info('  - 결재 대기 문서 5건 + 결재 단계 생성');
    }

    /**
     * 예상 지출 데이터 생성
     */
    private function seedExpectedExpenses(): void
    {
        $today = Carbon::today();
        $thisMonth = $today->copy()->startOfMonth();
        $lastMonth = $today->copy()->subMonth()->startOfMonth();

        $expenses = [
            // 이번 달 지출
            ['type' => 'purchase', 'amount' => 5000000, 'status' => 'paid', 'date' => $thisMonth->copy()->addDays(5)],
            ['type' => 'purchase', 'amount' => 3000000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(15)],
            ['type' => 'salary', 'amount' => 25000000, 'status' => 'paid', 'date' => $thisMonth->copy()->addDays(25)],
            ['type' => 'insurance', 'amount' => 2500000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(28)],
            ['type' => 'rent', 'amount' => 3000000, 'status' => 'paid', 'date' => $thisMonth->copy()->addDays(1)],
            ['type' => 'utilities', 'amount' => 500000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(20)],
            ['type' => 'tax', 'amount' => 1500000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(25)],
            ['type' => 'other', 'amount' => 2000000, 'status' => 'paid', 'date' => $thisMonth->copy()->addDays(10)],
            // 가지급금/선급금
            ['type' => 'suspense', 'amount' => 5000000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(3)],
            ['type' => 'suspense', 'amount' => 3000000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(12)],
            ['type' => 'advance', 'amount' => 2000000, 'status' => 'pending', 'date' => $thisMonth->copy()->addDays(8)],
            // 연체 (지난 달)
            ['type' => 'purchase', 'amount' => 1500000, 'status' => 'pending', 'date' => $lastMonth->copy()->addDays(20)],
        ];

        foreach ($expenses as $expense) {
            ExpectedExpense::create([
                'tenant_id' => $this->tenantId,
                'expected_payment_date' => $expense['date'],
                'transaction_type' => $expense['type'],
                'amount' => $expense['amount'],
                'payment_status' => $expense['status'],
                'approval_status' => 'approved',
                'description' => ExpectedExpense::TRANSACTION_TYPES[$expense['type']].' 지출',
                'created_by' => $this->userId,
            ]);
        }

        $this->command->info('  - 예상 지출 12건 생성');
    }

    /**
     * 입금 데이터 생성
     */
    private function seedDeposits(): void
    {
        $today = Carbon::today();
        $thisMonth = $today->copy()->startOfMonth();

        $deposits = [
            // 오늘 입금
            ['amount' => 5000000, 'method' => 'transfer', 'date' => $today, 'client' => '(주)테스트고객A'],
            ['amount' => 3000000, 'method' => 'transfer', 'date' => $today, 'client' => '(주)테스트고객B'],
            // 이번 달 입금
            ['amount' => 10000000, 'method' => 'transfer', 'date' => $thisMonth->copy()->addDays(5), 'client' => '(주)테스트고객C'],
            ['amount' => 7500000, 'method' => 'card', 'date' => $thisMonth->copy()->addDays(10), 'client' => '(주)테스트고객D'],
            ['amount' => 15000000, 'method' => 'transfer', 'date' => $thisMonth->copy()->addDays(15), 'client' => '(주)테스트고객E'],
            ['amount' => 8000000, 'method' => 'check', 'date' => $thisMonth->copy()->addDays(20), 'client' => '(주)테스트고객F'],
        ];

        foreach ($deposits as $deposit) {
            Deposit::create([
                'tenant_id' => $this->tenantId,
                'deposit_date' => $deposit['date'],
                'amount' => $deposit['amount'],
                'payment_method' => $deposit['method'],
                'client_name' => $deposit['client'],
                'description' => $deposit['client'].' 입금',
                'created_by' => $this->userId,
            ]);
        }

        $this->command->info('  - 입금 6건 생성');
    }

    /**
     * 채권추심 데이터 생성
     */
    private function seedBadDebts(): void
    {
        // 먼저 테스트 거래처 생성
        $clients = $this->ensureTestClients();

        $badDebts = [
            // 추심중
            ['client_idx' => 0, 'amount' => 5000000, 'status' => BadDebt::STATUS_COLLECTING, 'days' => 45],
            ['client_idx' => 1, 'amount' => 3000000, 'status' => BadDebt::STATUS_COLLECTING, 'days' => 60],
            // 법적조치
            ['client_idx' => 2, 'amount' => 8000000, 'status' => BadDebt::STATUS_LEGAL_ACTION, 'days' => 120],
            // 회수완료 (올해)
            ['client_idx' => 3, 'amount' => 2000000, 'status' => BadDebt::STATUS_RECOVERED, 'days' => 30, 'closed' => true],
            ['client_idx' => 4, 'amount' => 1500000, 'status' => BadDebt::STATUS_RECOVERED, 'days' => 45, 'closed' => true],
            // 대손처리
            ['client_idx' => 5, 'amount' => 10000000, 'status' => BadDebt::STATUS_BAD_DEBT, 'days' => 365, 'closed' => true],
        ];

        foreach ($badDebts as $debt) {
            $occurredAt = Carbon::today()->subDays($debt['days']);

            BadDebt::create([
                'tenant_id' => $this->tenantId,
                'client_id' => $clients[$debt['client_idx']]->id ?? null,
                'debt_amount' => $debt['amount'],
                'status' => $debt['status'],
                'overdue_days' => $debt['days'],
                'assigned_user_id' => $this->userId,
                'occurred_at' => $occurredAt,
                'closed_at' => isset($debt['closed']) ? Carbon::today() : null,
                'is_active' => ! isset($debt['closed']),
                'created_by' => $this->userId,
            ]);
        }

        $this->command->info('  - 채권추심 6건 생성');
    }

    /**
     * 테스트 거래처 생성
     */
    private function ensureTestClients(): array
    {
        $clientNames = [
            '(주)문제거래처A',
            '(주)문제거래처B',
            '(주)문제거래처C',
            '(주)정상거래처D',
            '(주)정상거래처E',
            '(주)대손거래처F',
        ];

        $clients = [];

        foreach ($clientNames as $i => $name) {
            $clients[] = Client::firstOrCreate(
                ['tenant_id' => $this->tenantId, 'client_code' => 'T'.$this->tenantId.'-'.str_pad($i + 1, 3, '0', STR_PAD_LEFT)],
                [
                    'name' => $name,
                    'is_active' => true,
                    'client_type' => 'company',
                ]
            );
        }

        return $clients;
    }

    /**
     * 거래처 미수금/여신한도 업데이트
     */
    private function updateClientBalances(): void
    {
        // 기존 거래처 중 일부에 미수금/여신한도 설정
        $clients = Client::where('tenant_id', $this->tenantId)
            ->where('is_active', true)
            ->limit(5)
            ->get();

        $balances = [
            ['outstanding' => 15000000, 'limit' => 10000000],  // 한도 초과
            ['outstanding' => 8000000, 'limit' => 10000000],   // 정상
            ['outstanding' => 12000000, 'limit' => 10000000],  // 한도 초과
            ['outstanding' => 5000000, 'limit' => 20000000],   // 정상
            ['outstanding' => 25000000, 'limit' => 20000000],  // 한도 초과
        ];

        foreach ($clients as $i => $client) {
            if (isset($balances[$i])) {
                $client->update([
                    'outstanding_balance' => $balances[$i]['outstanding'],
                    'credit_limit' => $balances[$i]['limit'],
                ]);
            }
        }

        $this->command->info('  - 거래처 미수금/여신한도 업데이트 '.min(count($clients), 5).'건');
    }
}
