<?php

namespace App\Services;

use App\Models\Members\User;
use App\Models\Members\UserTenant;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class AccountService extends Service
{
    /**
     * 회원 탈퇴 (SAM 완전 탈퇴)
     * - 모든 테넌트에서 탈퇴
     * - 사용자 계정 Soft Delete
     */
    public function withdraw(array $data): array
    {
        $userId = $this->apiUserId();
        $user = User::find($userId);

        if (! $user) {
            throw new NotFoundHttpException(__('error.not_found_resource', ['resource' => '사용자']));
        }

        // 비밀번호 확인
        if (! password_verify($data['password'], $user->password)) {
            throw new BadRequestHttpException(__('error.account.invalid_password'));
        }

        return DB::transaction(function () use ($user, $data) {
            // 1. 모든 테넌트 연결 해제 (soft delete)
            UserTenant::where('user_id', $user->id)->delete();

            // 2. 탈퇴 사유 저장 (options에 기록)
            $options = $user->options ?? [];
            $options['withdrawal'] = [
                'reason' => $data['reason'] ?? null,
                'detail' => $data['detail'] ?? null,
                'withdrawn_at' => now()->toIso8601String(),
            ];
            $user->options = $options;
            $user->save();

            // 3. 사용자 soft delete
            $user->delete();

            // 4. 토큰 삭제
            $user->tokens()->delete();

            return [
                'withdrawn_at' => now()->toIso8601String(),
            ];
        });
    }

    /**
     * 사용 중지 (특정 테넌트에서만 탈퇴)
     */
    public function suspend(): array
    {
        $userId = $this->apiUserId();
        $tenantId = $this->tenantId();

        $userTenant = UserTenant::where('user_id', $userId)
            ->where('tenant_id', $tenantId)
            ->first();

        if (! $userTenant) {
            throw new NotFoundHttpException(__('error.account.tenant_membership_not_found'));
        }

        return DB::transaction(function () use ($userTenant, $userId, $tenantId) {
            // 1. 현재 테넌트에서 비활성화
            $userTenant->is_active = false;
            $userTenant->left_at = now();
            $userTenant->save();

            // 2. 다른 활성 테넌트가 있으면 기본 테넌트 변경
            $otherActiveTenant = UserTenant::where('user_id', $userId)
                ->where('tenant_id', '!=', $tenantId)
                ->where('is_active', true)
                ->first();

            if ($otherActiveTenant) {
                // 다른 테넌트로 기본 변경
                UserTenant::where('user_id', $userId)->update(['is_default' => false]);
                $otherActiveTenant->is_default = true;
                $otherActiveTenant->save();

                return [
                    'suspended' => true,
                    'new_default_tenant_id' => $otherActiveTenant->tenant_id,
                ];
            }

            return [
                'suspended' => true,
                'new_default_tenant_id' => null,
            ];
        });
    }

    /**
     * 약관 동의 정보 조회
     */
    public function getAgreements(): array
    {
        $userId = $this->apiUserId();
        $user = User::find($userId);

        if (! $user) {
            throw new NotFoundHttpException(__('error.not_found_resource', ['resource' => '사용자']));
        }

        $options = $user->options ?? [];
        $agreements = $options['agreements'] ?? self::getDefaultAgreements();

        return [
            'agreements' => $agreements,
            'types' => self::getAgreementTypes(),
        ];
    }

    /**
     * 약관 동의 정보 수정
     */
    public function updateAgreements(array $data): array
    {
        $userId = $this->apiUserId();
        $user = User::find($userId);

        if (! $user) {
            throw new NotFoundHttpException(__('error.not_found_resource', ['resource' => '사용자']));
        }

        $options = $user->options ?? [];
        $currentAgreements = $options['agreements'] ?? self::getDefaultAgreements();

        // 수신 데이터로 업데이트
        foreach ($data['agreements'] as $agreement) {
            $type = $agreement['type'];
            if (isset($currentAgreements[$type])) {
                $currentAgreements[$type]['agreed'] = $agreement['agreed'];
                $currentAgreements[$type]['agreed_at'] = $agreement['agreed']
                    ? now()->toIso8601String()
                    : null;
            }
        }

        $options['agreements'] = $currentAgreements;
        $user->options = $options;
        $user->save();

        return [
            'agreements' => $currentAgreements,
        ];
    }

    /**
     * 기본 약관 동의 항목
     */
    public static function getDefaultAgreements(): array
    {
        return [
            'terms' => [
                'type' => 'terms',
                'label' => '이용약관',
                'required' => true,
                'agreed' => false,
                'agreed_at' => null,
            ],
            'privacy' => [
                'type' => 'privacy',
                'label' => '개인정보 처리방침',
                'required' => true,
                'agreed' => false,
                'agreed_at' => null,
            ],
            'marketing' => [
                'type' => 'marketing',
                'label' => '마케팅 정보 수신',
                'required' => false,
                'agreed' => false,
                'agreed_at' => null,
            ],
            'push' => [
                'type' => 'push',
                'label' => '푸시 알림 수신',
                'required' => false,
                'agreed' => false,
                'agreed_at' => null,
            ],
            'email' => [
                'type' => 'email',
                'label' => '이메일 수신',
                'required' => false,
                'agreed' => false,
                'agreed_at' => null,
            ],
            'sms' => [
                'type' => 'sms',
                'label' => 'SMS 수신',
                'required' => false,
                'agreed' => false,
                'agreed_at' => null,
            ],
        ];
    }

    /**
     * 약관 유형 레이블
     */
    public static function getAgreementTypes(): array
    {
        return [
            'terms' => '이용약관',
            'privacy' => '개인정보 처리방침',
            'marketing' => '마케팅 정보 수신',
            'push' => '푸시 알림 수신',
            'email' => '이메일 수신',
            'sms' => 'SMS 수신',
        ];
    }

    /**
     * 탈퇴 사유 목록
     */
    public static function getWithdrawalReasons(): array
    {
        return [
            'not_using' => '서비스를 더 이상 사용하지 않음',
            'difficult' => '사용하기 어려움',
            'alternative' => '다른 서비스 이용',
            'privacy' => '개인정보 보호 우려',
            'other' => '기타',
        ];
    }
}
