<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\UserDomain;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Carbon\Carbon;

class UserDomainController extends Controller
{
    public function buyDomain()
    {
        $subdomains = DB::table('subdomain_settings')->where('status', 'active')->orderBy('domain_name')->get();
        return view('user.buy-domain', compact('subdomains'));
    }

    public function checkDomain(Request $request)
    {
        $request->validate([
            'desired_subdomain' => 'required|string|regex:/^[a-zA-Z0-9-]+$/',
            'selected_domain' => 'required|string'
        ]);

        $desired = strtolower(trim($request->desired_subdomain));
        $ext = trim($request->selected_domain);
        $fullDomain = $desired . '.' . $ext;

        $exists = UserDomain::where('domain_name', $fullDomain)->exists();
        $subdomainSetting = DB::table('subdomain_settings')->where('domain_name', $ext)->first();

        if ($exists) {
            return back()->with('error', "Sorry! '$fullDomain' is already taken.");
        }

        return back()->with([
            'success' => "Congratulations! '$fullDomain' is available.",
            'checked_domain' => $desired,
            'checked_ext' => $ext,
            'domain_id' => $subdomainSetting->id,
            'monthly_price' => $subdomainSetting->price_per_month
        ]);
    }

    public function purchaseDomain(Request $request)
    {
        $request->validate([
            'desired_subdomain' => 'required|string',
            'selected_domain' => 'required|string',
            'selected_subdomain_id' => 'required|integer',
            'months' => 'required|integer|in:1,3,6,12'
        ]);

        $user = Auth::user();
        $months = (int) $request->months; 
        $fullDomain = strtolower(trim($request->desired_subdomain)) . '.' . trim($request->selected_domain);
        
        $pricing = DB::table('subdomain_settings')->where('id', $request->selected_subdomain_id)->first();
        if (!$pricing) return back()->with('error', 'Invalid domain configuration!');

        $baseTotal = $pricing->price_per_month * $months;
        $discountPercent = 0;
        if ($months == 3) $discountPercent = 10;
        elseif ($months == 6) $discountPercent = 15;
        elseif ($months == 12) $discountPercent = 40;

        $discountAmount = ($baseTotal * $discountPercent) / 100;
        $totalPrice = $baseTotal - $discountAmount;

        if ($user->balance < $totalPrice) {
            return back()->with('error', "Insufficient balance! You need ৳{$totalPrice}");
        }

        if (UserDomain::where('domain_name', $fullDomain)->exists()) {
            return back()->with('error', 'Domain is already taken!');
        }

        DB::beginTransaction();
        try {
            DB::table('user_domains')->insert([
                'user_id' => $user->id,
                'domain_name' => $fullDomain,
                'website_url' => 'http://' . $fullDomain,
                'monthly_price' => $pricing->price_per_month,
                'expiry_date' => now()->addMonths($months),
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now()
            ]);

            DB::table('users')->where('id', $user->id)->decrement('balance', $totalPrice);

            $desc = "Purchase: $fullDomain ($months Months)";
            if ($discountPercent > 0) $desc .= " - Saved $discountPercent%";

            DB::table('transactions')->insert([
                'user_id' => $user->id,
                'transaction_type' => 'debit',
                'amount' => $totalPrice,
                'description' => $desc,
                'status' => 'approved',
                'created_at' => now()
            ]);

            DB::commit();
            return redirect()->route('user.domain.index')->with('success', "Success! Your domain $fullDomain is now active.");
        } catch (\Exception $e) {
            DB::rollback();
            return back()->with('error', 'System Error: Failed to purchase domain.');
        }
    }

    public function myDomains()
    {
        $domains = UserDomain::where('user_id', Auth::id())->orderBy('id', 'desc')->paginate(12);
        return view('user.domains.index', compact('domains'));
    }

    public function manageDomain($id)
    {
        $domain = UserDomain::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
        
        $settings = DB::table('subdomain_settings')->get();
        $cf_creds = null;
        foreach ($settings as $setting) {
            if (str_ends_with($domain->domain_name, $setting->domain_name)) {
                $cf_creds = $setting;
                break;
            }
        }
        
        if (!$cf_creds) return back()->with('error', 'System Error: Parent domain settings not found.');

        $dns_list = [];
        $current_ns_records = [];
        
        $response = Http::withHeaders([
            'X-Auth-Email' => $cf_creds->cloudflare_email,
            'X-Auth-Key' => $cf_creds->cloudflare_api_key,
            'Content-Type' => 'application/json'
        ])->withoutVerifying()->get("https://api.cloudflare.com/client/v4/zones/{$cf_creds->cloudflare_zone_id}/dns_records?per_page=100");

        if ($response->successful()) {
            $result = $response->json()['result'] ?? [];
            foreach ($result as $record) {
                if ($record['name'] == $domain->domain_name || str_ends_with($record['name'], "." . $domain->domain_name)) {
                    if ($record['type'] == 'NS' && $record['name'] == $domain->domain_name) {
                        $current_ns_records[] = $record['content'];
                    }
                    $dns_list[] = $record;
                }
            }
        }

        $is_custom_ns = count($current_ns_records) > 0;
        $renew_base_price = $domain->monthly_price + ($domain->monthly_price * 0.40);

        return view('user.domains.manage', compact('domain', 'dns_list', 'current_ns_records', 'is_custom_ns', 'cf_creds', 'renew_base_price'));
    }

    public function updateDNS(Request $request, $id)
    {
        $domain = UserDomain::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
        
        if ($domain->status != 'active' || Carbon::parse($domain->expiry_date)->isPast()) {
            return back()->with('error', 'Action Blocked! Domain is expired or suspended. DNS management is disabled.');
        }

        $cf_creds = DB::table('subdomain_settings')->where('domain_name', substr(strstr($domain->domain_name, '.'), 1))->first();
        if (!$cf_creds) return back()->with('error', 'API Credentials not found.');

        $action = $request->action;
        $baseUrl = "https://api.cloudflare.com/client/v4/zones/{$cf_creds->cloudflare_zone_id}/dns_records";
        $headers = [
            'X-Auth-Email' => $cf_creds->cloudflare_email,
            'X-Auth-Key' => $cf_creds->cloudflare_api_key,
            'Content-Type' => 'application/json'
        ];

        if ($action == 'update_ns') {
            $all_records = Http::withHeaders($headers)->withoutVerifying()->get("$baseUrl?per_page=100")->json()['result'] ?? [];
            foreach ($all_records as $rec) {
                if (($rec['name'] == $domain->domain_name && $rec['type'] == 'NS') || ($rec['name'] == $domain->domain_name && $rec['type'] == 'A')) {
                    Http::withHeaders($headers)->withoutVerifying()->delete("$baseUrl/" . $rec['id']);
                }
            }

            if ($request->ns_type == 'custom') {
                $ns1 = trim($request->ns1);
                $ns2 = trim($request->ns2);
                if ($ns1 && $ns2) {
                    $added_ips = [];
                    foreach ([$ns1, $ns2] as $ns) {
                        Http::withHeaders($headers)->withoutVerifying()->post($baseUrl, [
                            'type' => 'NS', 'name' => $domain->domain_name, 'content' => $ns, 'ttl' => 1
                        ]);
                        $ip = gethostbyname($ns);
                        if ($ip != $ns && filter_var($ip, FILTER_VALIDATE_IP) && !in_array($ip, $added_ips)) {
                            Http::withHeaders($headers)->withoutVerifying()->post($baseUrl, [
                                'type' => 'A', 'name' => $domain->domain_name, 'content' => $ip, 'ttl' => 1, 'proxied' => false
                            ]);
                            $added_ips[] = $ip;
                        }
                    }
                    return back()->with('success', 'Custom Nameservers Updated Successfully! (IPs Auto-Detected)');
                }
                return back()->with('error', 'Both nameserver fields are required.');
            }
            return back()->with('success', 'Reset to Default Hosting Nameservers.');
        }

        if ($action == 'add_record' || $action == 'edit_record') {
            $type = $request->type;
            $name = trim($request->record_name);
            $final_name = ($name == '@' || $name == '') ? $domain->domain_name : (str_ends_with($name, $domain->domain_name) ? $name : $name . "." . $domain->domain_name);

            $is_proxied = in_array($type, ['A', 'AAAA', 'CNAME']) ? $request->has('proxied') : false;

            $data = [
                'type' => $type, 
                'name' => $final_name, 
                'content' => trim($request->content), 
                'ttl' => 1, 
                'proxied' => $is_proxied
            ];
            
            if (in_array($type, ['MX', 'SRV'])) {
                $data['priority'] = (int)$request->priority ?? 10;
            }

            if ($action == 'edit_record') {
                $response = Http::withHeaders($headers)->withoutVerifying()->put("$baseUrl/{$request->record_id}", $data);
                $msg = "Record Updated Successfully!";
            } else {
                $response = Http::withHeaders($headers)->withoutVerifying()->post($baseUrl, $data);
                $msg = "Record Added Successfully!";
            }

            if ($response->successful() && $response->json()['success']) return back()->with('success', $msg);
            return back()->with('error', "Cloudflare Error: " . ($response->json()['errors'][0]['message'] ?? 'Unknown Error'));
        }

        if ($action == 'delete_record') {
            $response = Http::withHeaders($headers)->withoutVerifying()->delete("$baseUrl/{$request->record_id}");
            if ($response->successful()) return back()->with('success', 'DNS Record Deleted.');
            return back()->with('error', 'Failed to delete record.');
        }

        return back()->with('error', 'Invalid Action!');
    }

    public function renewDomain(Request $request, $id)
    {
        $domain = UserDomain::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
        $months = (int) $request->months;
        
        $buying_price = $domain->monthly_price;
        $renew_base_price = $buying_price + ($buying_price * 0.40);
        
        $base_total = $renew_base_price * $months;
        $discount_percent = 0;
        if ($months == 3) $discount_percent = 2;
        elseif ($months == 6) $discount_percent = 5;
        elseif ($months == 12) $discount_percent = 10;

        $discount_amount = ($base_total * $discount_percent) / 100;
        $total_cost = $base_total - $discount_amount;
        
        $user = Auth::user();
        if ($user->balance < $total_cost) {
            return back()->with('error', "Insufficient balance. You need ৳" . number_format($total_cost, 2));
        }
        
        DB::beginTransaction();
        try {
            DB::table('users')->where('id', $user->id)->decrement('balance', $total_cost);
            
            $current_expiry = strtotime($domain->expiry_date) < time() ? time() : strtotime($domain->expiry_date);
            $new_expiry = date('Y-m-d', strtotime("+$months months", $current_expiry));
            
            $domain->expiry_date = $new_expiry;
            $domain->status = 'active';
            $domain->save();
            
            DB::table('transactions')->insert([
                'user_id' => $user->id,
                'transaction_type' => 'debit',
                'amount' => $total_cost,
                'description' => "Renew Domain: {$domain->domain_name} ({$months} M) - Inc. 40% Charge",
                'status' => 'approved',
                'created_at' => now()
            ]);
            
            DB::commit();
            return back()->with('success', 'Domain renewed successfully! DNS Management unlocked.');
        } catch (\Exception $e) {
            DB::rollback();
            return back()->with('error', 'Renewal failed! Please try again.');
        }
    }
}
