<?php

namespace App\Services;

use App\Models\Customer;
use App\Notifications\CustomerResetPasswordNotification;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Carbon\Carbon;

class CustomerPasswordResetService
{
    /**
     * Password reset table name.
     */
    protected $table = 'customer_password_resets';

    /**
     * Token expiry time in minutes.
     */
    protected $expiry = 60;

    public function __construct()
    {
        $this->expiry = config('auth.passwords.customers.expire', 60);
    }

    /**
     * Send password reset link to customer.
     */
    public function sendResetLink(string $email): array
    {
        $customer = Customer::where('email', $email)->first();

        if (!$customer) {
            return [
                'success' => false,
                'message' => 'We can\'t find a customer with that email address.'
            ];
        }

        if (!$customer->isActive()) {
            return [
                'success' => false,
                'message' => 'Your account is not active. Please contact support.'
            ];
        }

        // Delete existing tokens for this email
        $this->deleteExistingTokens($email);

        // Generate new token
        $token = $this->createToken();

        // Store token in database
        DB::table($this->table)->insert([
            'email' => $email,
            'token' => Hash::make($token),
            'created_at' => Carbon::now()
        ]);

        // Send notification
        $customer->notify(new CustomerResetPasswordNotification($token));

        return [
            'success' => true,
            'message' => 'Password reset link has been sent to your email address.'
        ];
    }

    /**
     * Reset customer password.
     */
    public function resetPassword(string $email, string $token, string $password): array
    {
        $customer = Customer::where('email', $email)->first();

        if (!$customer) {
            return [
                'success' => false,
                'message' => 'We can\'t find a customer with that email address.'
            ];
        }

        $resetRecord = DB::table($this->table)
            ->where('email', $email)
            ->first();

        if (!$resetRecord) {
            return [
                'success' => false,
                'message' => 'Invalid or expired password reset token.'
            ];
        }

        // Check if token is expired
        if (Carbon::parse($resetRecord->created_at)->addMinutes($this->expiry)->isPast()) {
            $this->deleteExistingTokens($email);
            return [
                'success' => false,
                'message' => 'Password reset token has expired.'
            ];
        }

        // Verify token
        if (!Hash::check($token, $resetRecord->token)) {
            return [
                'success' => false,
                'message' => 'Invalid password reset token.'
            ];
        }

        // Update customer password
        $customer->update([
            'password' => $password // Will be hashed by the model
        ]);

        // Delete the token
        $this->deleteExistingTokens($email);

        return [
            'success' => true,
            'message' => 'Your password has been reset successfully.'
        ];
    }

    /**
     * Verify if reset token is valid.
     */
    public function verifyToken(string $email, string $token): bool
    {
        $resetRecord = DB::table($this->table)
            ->where('email', $email)
            ->first();

        if (!$resetRecord) {
            return false;
        }

        // Check if token is expired
        if (Carbon::parse($resetRecord->created_at)->addMinutes($this->expiry)->isPast()) {
            $this->deleteExistingTokens($email);
            return false;
        }

        return Hash::check($token, $resetRecord->token);
    }

    /**
     * Delete existing tokens for email.
     */
    protected function deleteExistingTokens(string $email): void
    {
        DB::table($this->table)->where('email', $email)->delete();
    }

    /**
     * Generate a random token.
     */
    protected function createToken(): string
    {
        return Str::random(64);
    }

    /**
     * Clean up expired tokens.
     */
    public function cleanupExpiredTokens(): int
    {
        return DB::table($this->table)
            ->where('created_at', '<', Carbon::now()->subMinutes($this->expiry))
            ->delete();
    }
}
