<?php

namespace App\Services\Verification\Drivers;

use App\Services\Verification\Contracts\VerificationProviderInterface;
use App\Services\Verification\DTOs\AadhaarBasicResult;
use App\Services\Verification\DTOs\AadhaarOtpResult;
use App\Services\Verification\DTOs\AadhaarPanLinkResult;
use App\Services\Verification\DTOs\AadhaarVerificationResult;
use App\Services\Verification\DTOs\GstVerificationResult;
use App\Services\Verification\DTOs\PanVerificationResult;
use App\Services\Verification\DTOs\BankVerificationResult;
use Illuminate\Support\Str;

class MockDriver implements VerificationProviderInterface
{
    public function verifyPan(string $panNumber, ?string $fullName = null, ?string $dob = null): PanVerificationResult
    {
        $panNumber = strtoupper(trim($panNumber));
        if (!preg_match('/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/', $panNumber)) {
            return new PanVerificationResult(
                valid: false,
                panNumber: $panNumber,
                rawData: ['message' => 'Invalid PAN format']
            );
        }

        $isIndividual = in_array($panNumber[3], ['P', 'H']);
        $category = match($panNumber[3]) {
            'P' => 'individual',
            'C' => 'company',
            'H' => 'hindu_undivided_family',
            'F' => 'firm',
            'A' => 'association_of_persons',
            'T' => 'trust',
            default => 'other'
        };

        return new PanVerificationResult(
            valid: true,
            panNumber: $panNumber,
            fullName: 'MOCK VERIFIED HOLDER',
            firstName: 'MOCK',
            middleName: 'VERIFIED',
            lastName: 'HOLDER',
            category: $category,
            isIndividual: $isIndividual,
            rawData: [
                'status' => 'valid',
                'pan_status' => 'EXISTING AND VALID',
                'aadhaar_seeding_status' => 'LINKED'
            ]
        );
    }

    public function sendAadhaarOtp(string $aadhaarNumber): AadhaarOtpResult
    {
        if (!preg_match('/^[0-9]{12}$/', $aadhaarNumber)) {
            return new AadhaarOtpResult(
                otpSent: false,
                message: 'Invalid Aadhaar number format. Must be 12 digits.',
                rawData: ['status' => 'failed']
            );
        }

        $clientId = 'mock_client_' . Str::random(16);

        return new AadhaarOtpResult(
            otpSent: true,
            clientId: $clientId,
            message: 'OTP sent successfully to registered mobile number.',
            rawData: [
                'status' => 'success',
                'client_id' => $clientId,
                'otp_sent' => true
            ]
        );
    }

    public function verifyAadhaarOtp(string $otp, string $clientId): AadhaarVerificationResult
    {
        if (!str_starts_with($clientId, 'mock_client_')) {
            return new AadhaarVerificationResult(
                valid: false,
                aadhaarNumber: '',
                rawData: ['message' => 'Invalid client_id session.']
            );
        }

        if ($otp !== '123456') {
            return new AadhaarVerificationResult(
                valid: false,
                aadhaarNumber: '',
                rawData: ['message' => 'Incorrect OTP. Verification failed.']
            );
        }

        return new AadhaarVerificationResult(
            valid: true,
            aadhaarNumber: '123456789012',
            fullName: 'MOCK AADHAAR HOLDER',
            gender: 'MALE',
            dob: '1990-01-01',
            address: [
                'line1' => 'Flat 101, Mock Tower',
                'city' => 'Mumbai',
                'district' => 'Mumbai',
                'state' => 'Maharashtra',
                'pincode' => '400001'
            ],
            photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
            rawData: [
                'status' => 'success',
                'mobile_verified' => true,
                'email_verified' => false
            ]
        );
    }

    public function verifyAadhaarBasic(string $aadhaarNumber): AadhaarBasicResult
    {
        if (!preg_match('/^[0-9]{12}$/', $aadhaarNumber)) {
            return new AadhaarBasicResult(
                valid: false,
                aadhaarNumber: $aadhaarNumber,
                rawData: ['message' => 'Invalid Aadhaar format']
            );
        }

        return new AadhaarBasicResult(
            valid: true,
            aadhaarNumber: $aadhaarNumber,
            ageBand: '30-40',
            gender: 'FEMALE',
            state: 'Delhi',
            rawData: [
                'status' => 'valid',
                'exists' => true
            ]
        );
    }

    public function checkAadhaarPanLink(string $aadhaarNumber, string $panNumber): AadhaarPanLinkResult
    {
        if (!preg_match('/^[0-9]{12}$/', $aadhaarNumber) || !preg_match('/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/', strtoupper($panNumber))) {
            return new AadhaarPanLinkResult(
                linked: false,
                panNumber: $panNumber,
                aadhaarNumber: $aadhaarNumber,
                message: 'Invalid Aadhaar or PAN formatting.',
                rawData: ['status' => 'failed']
            );
        }

        return new AadhaarPanLinkResult(
            linked: true,
            panNumber: strtoupper($panNumber),
            aadhaarNumber: $aadhaarNumber,
            message: 'Aadhaar and PAN are linked.',
            rawData: [
                'status' => 'success',
                'is_linked' => true
            ]
        );
    }

    public function verifyGst(string $gstin): GstVerificationResult
    {
        $gstin = strtoupper(trim($gstin));
        if (!preg_match('/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/', $gstin)) {
            return new GstVerificationResult(
                valid: false,
                gstin: $gstin,
                rawData: ['message' => 'Invalid GSTIN format.']
            );
        }

        return new GstVerificationResult(
            valid: true,
            gstin: $gstin,
            legalName: 'MOCK BUSINESS PRIVATE LIMITED',
            tradeName: 'MOCK ENTERPRISES',
            status: 'Active',
            registrationDate: '2018-04-15',
            taxpayerType: 'Regular',
            address: [
                'building_name' => 'Mock Palace',
                'street' => 'Mock Street',
                'city' => 'Bengaluru',
                'state' => 'Karnataka',
                'pincode' => '560001'
            ],
            rawData: [
                'status' => 'Active',
                'compliance_rating' => 'Good'
            ]
        );
    }

    public function verifyBank(string $accountNumber, string $ifsc): BankVerificationResult
    {
        $accountNumber = trim($accountNumber);
        $ifsc = strtoupper(trim($ifsc));

        if (empty($accountNumber) || empty($ifsc)) {
            return new BankVerificationResult(
                valid: false,
                accountNumber: $accountNumber,
                ifsc: $ifsc,
                rawData: ['message' => 'Account number or IFSC cannot be empty.']
            );
        }

        return new BankVerificationResult(
            valid: true,
            accountNumber: $accountNumber,
            ifsc: $ifsc,
            accountName: 'MOCK ACCOUNT HOLDER',
            bankName: 'MOCK BANK OF INDIA',
            rawData: [
                'status' => 'verified',
                'bank_response' => 'Account active and exists.'
            ]
        );
    }
}
