<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\Batch\BatchLog;
use App\Models\RegularContract;
use App\Models\User;
use App\Models\Park;
use App\Models\Ope;
use App\Services\ShjMailSendService;

/**
 * SHJ-12 未払い者通知処理サービス
 * 
 * 定期契約マスタより未払い者を取得し、通知処理またはオペレーターキュー追加を実行
 */
class ShjTwelveService
{
    /**
     * SHJメール送信サービス
     *
     * @var ShjMailSendService
     */
    protected $shjMailSendService;

    /**
     * コンストラクタ
     *
     * @param ShjMailSendService $shjMailSendService
     */
    public function __construct(ShjMailSendService $shjMailSendService)
    {
        $this->shjMailSendService = $shjMailSendService;
    }

    /**
     * 【処理1】定期契約マスタより未払い者を取得する
     * 
     * SQL条件:
     * - 解約フラグ = 0 (未解約)
     * - 授受フラグ = 0 (授受フラグOFF)
     * - 請求金額 > 0 (請求金額あり)
     *
     * @return array 未払い者リスト
     */
    public function getUnpaidUsers(): array
    {
        try {
            $query = DB::table('regular_contract as T1')
                ->select([
                    'T1.contract_id',           // 定期契約ID
                    'T2.user_seq',              // 利用者ID
                    'T2.user_name',             // 利用者名
                    'T2.user_manual_flag',      // 手動登録フラグ
                    'T2.user_mail',             // メールアドレス
                    'T2.user_mail_sub',         // 予備メールアドレス
                    'T2.park_id',               // 駐輪場ID (userテーブルから)
                    'T3.park_name',             // 駐輪場名
                    'T1.billing_amount'         // 請求金額
                ])
                ->join('user as T2', function($join) {
                    $join->on('T1.user_seq', '=', 'T2.user_seq');
                })
                ->join('park as T3', 'T1.park_id', '=', 'T3.park_id')
                ->where([
                    ['T1.contract_cancel_flag', '=', 0],  // 解約フラグ = 0
                    ['T1.contract_flag', '=', 0],         // 授受フラグ = 0
                ])
                ->where('T1.billing_amount', '>', 0)      // 請求金額 > 0
                ->get();

            Log::info('SHJ-12 未払い者取得完了', [
                'count' => $query->count(),
                'sql_conditions' => [
                    'contract_cancel_flag' => 0,
                    'contract_flag' => 0,
                    'billing_amount' => '> 0'
                ]
            ]);

            return $query->toArray();

        } catch (\Exception $e) {
            Log::error('SHJ-12 未払い者取得エラー', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }

    /**
     * 【処理2】未払い者への通知、またはオペレーターキュー追加処理
     * 
     * 各未払い者に対して以下の処理を実行:
     * 1. メール通知の実行 (SHJ-7連携)
     * 2. オペレーターキューへの追加 (opeテーブル)
     *
     * @param array $unpaidUsers 未払い者リスト
     * @return array 処理結果
     */
    public function processUnpaidUserNotifications(array $unpaidUsers): array
    {
        $notificationCount = 0;
        $queueCount = 0;
        $errors = [];
        $processParameters = [];

        try {
            DB::beginTransaction();

            foreach ($unpaidUsers as $user) {
                try {
                    // メール通知処理
                    $mailResult = $this->sendNotificationMail($user);
                    if ($mailResult['success']) {
                        $notificationCount++;
                    }

                    // オペレーターキュー追加処理
                    $queueResult = $this->addToOperatorQueue($user);
                    if ($queueResult['success']) {
                        $queueCount++;
                    }

                    // 処理パラメータ記録
                    $processParameters[] = [
                        'contract_id' => $user->contract_id,
                        'user_seq' => $user->user_seq,
                        'billing_amount' => $user->billing_amount,
                        'mail_sent' => $mailResult['success'],
                        'queue_added' => $queueResult['success']
                    ];

                } catch (\Exception $e) {
                    $errors[] = [
                        'contract_id' => $user->contract_id,
                        'error' => $e->getMessage()
                    ];
                    
                    Log::warning('SHJ-12 個別処理エラー', [
                        'contract_id' => $user->contract_id,
                        'user_seq' => $user->user_seq,
                        'error' => $e->getMessage()
                    ]);
                }
            }

            DB::commit();

            return [
                'success' => true,
                'notification_count' => $notificationCount,
                'queue_count' => $queueCount,
                'parameters' => $processParameters,
                'errors' => $errors,
                'message' => '未払い者通知処理完了'
            ];

        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('SHJ-12 通知処理全体エラー', [
                'error' => $e->getMessage(),
                'processed_count' => count($processParameters)
            ]);

            return [
                'success' => false,
                'notification_count' => $notificationCount,
                'queue_count' => $queueCount,
                'parameters' => $processParameters,
                'errors' => $errors,
                'message' => '通知処理エラー: ' . $e->getMessage(),
                'details' => $e->getTraceAsString()
            ];
        }
    }

    /**
     * 未払い者へのメール通知送信
     * 
     * SHJ-7 メール送信サービスを使用してメール通知を実行
     *
     * @param object $user 未払い者情報
     * @return array 送信結果
     */
    private function sendNotificationMail($user): array
    {
        try {
            // メールアドレスの確認
            $emailAddress = $user->user_mail ?: $user->user_mail_sub;
            
            if (empty($emailAddress)) {
                return [
                    'success' => false,
                    'message' => 'メールアドレスが設定されていません'
                ];
            }

            // SHJ-7 メール送信サービス呼び出し
            $mailParams = [
                'to_email' => $emailAddress,
                'user_name' => $user->user_name,
                'park_name' => $user->park_name,
                'billing_amount' => $user->billing_amount,
                'contract_id' => $user->contract_id
            ];

            $result = $this->shjMailSendService->sendUnpaidNotificationMail($mailParams);

            Log::info('SHJ-12 メール送信結果', [
                'contract_id' => $user->contract_id,
                'email' => $emailAddress,
                'success' => $result['success']
            ]);

            return $result;

        } catch (\Exception $e) {
            Log::error('SHJ-12 メール送信エラー', [
                'contract_id' => $user->contract_id,
                'error' => $e->getMessage()
            ]);

            return [
                'success' => false,
                'message' => 'メール送信エラー: ' . $e->getMessage()
            ];
        }
    }

    /**
     * オペレーターキューへの追加
     * 
     * opeテーブルにオペレーター処理キューとして登録
     *
     * @param object $user 未払い者情報
     * @return array 追加結果
     */
    private function addToOperatorQueue($user): array
    {
        try {
            $queueData = [
                'ope_device_id' => null,                    // デバイスID (未設定)
                'ope_process_name' => 'SHJ-12',            // プロセス名
                'ope_job_name' => '未払い者通知',            // ジョブ名
                'ope_status' => 'pending',                  // ステータス
                'ope_comment' => sprintf(
                    '契約ID:%s ユーザー:%s 金額:%s円',
                    $user->contract_id,
                    $user->user_name,
                    number_format($user->billing_amount)
                ),
                'ope_target_user_id' => $user->user_seq,    // 対象ユーザーID
                'ope_target_contract_id' => $user->contract_id, // 対象契約ID
                'ope_billing_amount' => $user->billing_amount,  // 請求金額
                'created_at' => now(),
                'updated_at' => now()
            ];

            // opeテーブルに挿入
            DB::table('ope')->insert($queueData);

            Log::info('SHJ-12 オペレーターキュー追加完了', [
                'contract_id' => $user->contract_id,
                'user_seq' => $user->user_seq,
                'billing_amount' => $user->billing_amount
            ]);

            return [
                'success' => true,
                'message' => 'オペレーターキューに追加しました'
            ];

        } catch (\Exception $e) {
            Log::error('SHJ-12 オペレーターキュー追加エラー', [
                'contract_id' => $user->contract_id,
                'error' => $e->getMessage()
            ]);

            return [
                'success' => false,
                'message' => 'オペレーターキュー追加エラー: ' . $e->getMessage()
            ];
        }
    }

    /**
     * 【処理3】バッチ処理ログを作成する
     * 
     * 統一BatchLogシステムを使用してSHJ-12の実行ログを記録
     *
     * @param string $status ステータス
     * @param array $parameters パラメータ
     * @param string $message メッセージ
     * @param int $executionCount 実行回数
     * @param int $successCount 成功回数
     * @param int $errorCount エラー回数
     * @return void
     */
    public function createBatchLog(
        string $status,
        array $parameters,
        string $message,
        int $executionCount = 0,
        int $successCount = 0,
        int $errorCount = 0
    ): void {
        try {
            BatchLog::createBatchLog(
                'SHJ-12',
                $status,
                $parameters,
                $message,
                [
                    'execution_count' => $executionCount,
                    'success_count' => $successCount,
                    'error_count' => $errorCount,
                    'process_type' => '未払い者通知処理',
                    'executed_at' => now()->toISOString()
                ]
            );

        } catch (\Exception $e) {
            Log::error('SHJ-12 バッチログ作成エラー', [
                'error' => $e->getMessage(),
                'status' => $status,
                'message' => $message
            ]);
        }
    }
}
