<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class cPanelController extends Controller
{
  public function login(Request $request)
{
  $username = $request->input('username');
  $type = $request->input('type');
  $app = $request->input('app');
  $whmusername = "root";

  $serverId = $request->input('serverid');

  // WHMCS veri tabanından accesshash değerini al
  try {
      $accessHash = DB::connection('whmcs')->table('tblservers')
          ->where('id', $serverId)
          ->value('accesshash');
          $servername = DB::connection('whmcs')->table('tblservers')
              ->where('id', $serverId)
              ->value('hostname');

      if (!$accessHash) {
          throw new Exception("Sunucu ID $serverId için accesshash bulunamadı.");
      }
  } catch (Exception $e) {
      error_log('Veri tabanı hatası: ' . $e->getMessage());
      die('Access hash bilgisi alınamadı.');
  }

  if ($type == "reselleraccount") {
    $query = "https://$servername:2087/json-api/create_user_session?api.version=1&user=$username&service=whostmgrd";
  }else {
    $query = "https://$servername:2087/json-api/create_user_session?api.version=1&user=$username&service=cpaneld&app=$app";
  }


  // cURL oturumunu başlat ve seçenekleri ayarla
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

  // Yetkilendirme başlığını ekle
  $header[0] = "Authorization: WHM $whmusername:" . preg_replace("'(\r|\n)'", "", $accessHash);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
  curl_setopt($curl, CURLOPT_URL, $query);

  // cURL yürüt ve sonucu al
  $result = curl_exec($curl);

  // Hata kontrolü
  if ($result === false) {
      error_log('cURL error: ' . curl_error($curl));
      curl_close($curl);
      die('Error occurred during cURL execution.');
  }

  // Sonucu işleme
  $decoded_response = json_decode($result, true);
  if (isset($decoded_response['data']['url'])) {
      $url = $decoded_response['data']['url'];
      curl_close($curl);
      return redirect($url);
  } else {
      error_log('Failed to create user session: ' . $result);
      curl_close($curl);
      die('Failed to create user session.');
  }
}

public function getResellerDomains($serverId, $resellerUsername)
{
    $whmusername = "root";

    try {
        $accessHash = DB::connection('whmcs')->table('tblservers')
            ->where('id', $serverId)
            ->value('accesshash');
        $servername = DB::connection('whmcs')->table('tblservers')
            ->where('id', $serverId)
            ->value('hostname');

        if (!$accessHash || !$servername) {
            throw new \Exception("AccessHash ya da Servername alınamadı.");
        }
    } catch (\Exception $e) {
        return response()->json(['error' => $e->getMessage()], 500);
    }

    $url = "https://$servername:2087/json-api/listaccts?api.version=1&searchtype=owner&search={$resellerUsername}";

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "Authorization: WHM $whmusername:" . preg_replace("'(\r|\n)'", '', $accessHash)
        ],
        CURLOPT_URL => $url
    ]);

    $response = curl_exec($curl);
    if ($response === false) {
        return response()->json(['error' => curl_error($curl)], 500);
    }
    curl_close($curl);

    $data = json_decode($response, true);

    if (isset($data['data']['acct'])) {
        // Sadece domain isimlerini döndürmek istiyorsan:
        $domains = array_map(fn($item) => $item['domain'], $data['data']['acct']);
        return response()->json(['domains' => $domains]);
    } else {
        return response()->json(['error' => 'Reseller domainleri alınamadı.', 'raw' => $data], 500);
    }
}
private function whmApiCall(int $serverId, string $endpoint, array $params = [], string $method = 'GET'): array
   {
       $whmusername = "root";

       $accessHash = DB::connection('whmcs')->table('tblservers')->where('id', $serverId)->value('accesshash');
       $servername = DB::connection('whmcs')->table('tblservers')->where('id', $serverId)->value('hostname');

       if (!$accessHash || !$servername) {
           return ['ok' => false, 'error' => 'WHMCS tblservers üzerinden accesshash/hostname alınamadı.'];
       }

       $accessHash = preg_replace("'(\r|\n)'", "", (string)$accessHash);

       $baseUrl = "https://{$servername}:2087/json-api/{$endpoint}";
       $params = array_merge(['api.version' => 1], $params);

       $curl = curl_init();

       $opts = [
           CURLOPT_SSL_VERIFYPEER => false, // prod’da mümkünse true yap
           CURLOPT_SSL_VERIFYHOST => false, // prod’da mümkünse 2 yap
           CURLOPT_RETURNTRANSFER => true,
           CURLOPT_TIMEOUT => 30,
           CURLOPT_HTTPHEADER => [
               "Authorization: WHM {$whmusername}:{$accessHash}",
               "Accept: application/json",
           ],
       ];

       if (strtoupper($method) === 'GET') {
           $url = $baseUrl . '?' . http_build_query($params);
           $opts[CURLOPT_URL] = $url;
       } else {
           $opts[CURLOPT_URL] = $baseUrl;
           $opts[CURLOPT_POST] = true;
           $opts[CURLOPT_POSTFIELDS] = http_build_query($params);
       }

       curl_setopt_array($curl, $opts);

       $response = curl_exec($curl);
       $err = curl_error($curl);
       $http = curl_getinfo($curl, CURLINFO_HTTP_CODE);
       curl_close($curl);

       if ($response === false) {
           return ['ok' => false, 'error' => "cURL error: {$err}"];
       }

       $json = json_decode($response, true);

       if ($http < 200 || $http >= 300) {
           return ['ok' => false, 'error' => "HTTP {$http}", 'raw' => $json ?: $response];
       }

       // WHM çoğu endpointte metadata.result döner
       $meta = $json['metadata'] ?? null;
       if (is_array($meta) && isset($meta['result']) && (int)$meta['result'] !== 1) {
           return ['ok' => false, 'error' => (string)($meta['reason'] ?? 'WHM API error'), 'raw' => $json];
       }

       return ['ok' => true, 'data' => $json];
   }

   /**
    * dumpzone çıktısını düzleştirir: data.record[0].record => gerçek kayıtlar
    */
   private function flattenDumpzoneRecords(array $dumpzone): array
   {
       // Senin debug çıktına göre doğru yol burası:
       $flat = $dumpzone['data']['record'][0]['record'] ?? null;
       if (is_array($flat)) return $flat;

       // fallback
       if (isset($dumpzone['data']['zone']) && is_array($dumpzone['data']['zone'])) return $dumpzone['data']['zone'];
       if (isset($dumpzone['data']['record']) && is_array($dumpzone['data']['record'])) {
           // wrapper olabilir
           if (isset($dumpzone['data']['record'][0]['record']) && is_array($dumpzone['data']['record'][0]['record'])) {
               return $dumpzone['data']['record'][0]['record'];
           }
           return $dumpzone['data']['record'];
       }

       return [];
   }

   /**
    * Domain zone verisini WHM'den çeker (dumpzone)
    */
   public function getZoneFromWhm(int $serverId, string $domain): array
   {
       $res = $this->whmApiCall($serverId, 'dumpzone', ['domain' => $domain], 'GET');
       if (!$res['ok']) return $res;

       $dump = $res['data'];
       $records = $this->flattenDumpzoneRecords($dump);

       return [
           'ok' => true,
           'zone' => $domain,
           'records' => $records,   // ham kayıtlar (A/MX/TXT/CNAME/SRV vs)
       ];
   }

   /**
    * Frontend'den gelen name'i cPanel FQDN formatına çevirir
    * @ -> domain.com.
    * mail -> mail.domain.com.
    * mail.domain.com -> mail.domain.com.
    */
   private function normalizeNameToFqdn(string $name, string $domain): string
   {
       $domain = rtrim($domain, '.');
       $name = trim($name);

       // @ veya boş ise root domain
       if ($name === '' || $name === '@') {
           return $domain . '.';
       }

       // Zaten FQDN ise (sonda nokta var)
       if (str_ends_with($name, '.')) {
           return $name;
       }

       // Eğer name zaten domain ile aynıysa
       if (strcasecmp($name, $domain) === 0) {
           return $domain . '.';
       }

       // Eğer name.domain.com formatındaysa
       if (str_ends_with(strtolower($name), '.' . strtolower($domain))) {
           return $name . '.';
       }

       // Sadece subdomain ise (mail, www vs) -> subdomain.domain.com.
       return $name . '.' . $domain . '.';
   }

   /**
    * Tek kayıt güncelle (editzonerecord)
    * Not: editzonerecord "line" ister, bu yüzden frontend’e Line göndermen şart.
    */
    public function updateZoneRecordFromWhm(int $serverId, string $domain, array $payload): array
    {
        // Beklediğimiz payload:
        // line, name, type, ttl, class, content/address/cname/exchange/txtdata... (type’a göre)
        $type = strtoupper(trim((string)($payload['type'] ?? '')));
        $line = (int)($payload['line'] ?? 0);

        if ($line <= 0 || $type === '') {
            return ['ok' => false, 'error' => 'line/type eksik.'];
        }

        // WHM editzonerecord paramları type’a göre değişiyor.
        // A için address, CNAME için cname, MX için exchange+preference, TXT için txtdata, SRV için target/port/priority/weight...
        $params = [
            'domain' => $domain,
            'line'   => $line,
            'type'   => $type,
        ];

        // Name'i FQDN formatına çevir (@ -> domain.com., mail -> mail.domain.com.)
        $rawName = $payload['name'] ?? '@';
        $params['name'] = $this->normalizeNameToFqdn($rawName, $domain);

        if (!empty($payload['ttl']))   $params['ttl']   = (int)$payload['ttl'];
        if (!empty($payload['class'])) $params['class'] = $payload['class'];

        // type-specific mapping
        switch ($type) {
            case 'A':
            case 'AAAA':
                $params['address'] = $payload['address'] ?? $payload['content'] ?? null;
                break;

            case 'CNAME':
                $params['cname'] = $payload['cname'] ?? $payload['content'] ?? null;
                break;

            case 'DNAME':
                $params['target'] = $payload['target'] ?? $payload['content'] ?? null;
                break;

            case 'TXT':
                $params['txtdata'] = $payload['txtdata'] ?? $payload['content'] ?? null;
                break;

            case 'MX':
                $params['exchange'] = $payload['exchange'] ?? $payload['content'] ?? null;
                $params['preference'] = (int)($payload['preference'] ?? 0);
                break;

            case 'NS':
                $params['nsdname'] = $payload['nsdname'] ?? $payload['content'] ?? null;
                break;

            case 'PTR':
                $params['ptrdname'] = $payload['ptrdname'] ?? $payload['content'] ?? null;
                break;

            case 'SRV':
                $params['target']   = $payload['target'] ?? null;
                $params['port']     = (int)($payload['port'] ?? 0);
                $params['priority'] = (int)($payload['priority'] ?? 0);
                $params['weight']   = (int)($payload['weight'] ?? 0);
                break;

            case 'CAA':
                $params['flag']  = (int)($payload['flag'] ?? 0);
                $params['tag']   = $payload['tag'] ?? 'issue';
                $params['value'] = $payload['value'] ?? null;
                break;

            case 'AFSDB':
                $params['subtype']  = (int)($payload['subtype'] ?? 1);
                $params['hostname'] = $payload['hostname'] ?? null;
                break;

            case 'DS':
                $params['keytag']     = (int)($payload['keytag'] ?? 0);
                $params['algorithm']  = (int)($payload['algorithm'] ?? 0);
                $params['digesttype'] = (int)($payload['digesttype'] ?? 0);
                $params['digest']     = $payload['digest'] ?? null;
                break;

            case 'HINFO':
                $params['cpu'] = $payload['cpu'] ?? null;
                $params['os']  = $payload['os'] ?? null;
                break;

            case 'LOC':
                $params['location'] = $payload['location'] ?? $payload['content'] ?? null;
                break;

            case 'NAPTR':
                $params['order']       = (int)($payload['order'] ?? 0);
                $params['preference']  = (int)($payload['preference'] ?? 0);
                $params['flags']       = $payload['flags'] ?? '';
                $params['service']     = $payload['service'] ?? '';
                $params['regexp']      = $payload['regexp'] ?? '';
                $params['replacement'] = $payload['replacement'] ?? '.';
                break;

            case 'RP':
                $params['mbox']     = $payload['mbox'] ?? null;
                $params['txtdname'] = $payload['txtdname'] ?? null;
                break;

            default:
                return ['ok' => false, 'error' => "Bu kayıt türü desteklenmiyor: {$type}"];
        }

        // Boş kalmış zorunlu alan kontrolü
        foreach ($params as $k => $v) {
            if ($v === null) {
                return ['ok' => false, 'error' => "Eksik alan: {$k}"];
            }
        }

        return $this->whmApiCall($serverId, 'editzonerecord', $params, 'POST');
    }

    /**
     * Yeni kayıt ekle (addzonerecord)
     */
    public function addZoneRecordFromWhm(int $serverId, string $domain, array $payload): array
    {
        $type = strtoupper(trim((string)($payload['type'] ?? '')));

        if ($type === '') {
            return ['ok' => false, 'error' => 'Type eksik.'];
        }

        $params = [
            'domain' => $domain,
            'type'   => $type,
        ];

        // Name'i FQDN formatına çevir (@ -> domain.com., mail -> mail.domain.com.)
        $rawName = $payload['name'] ?? '@';
        $params['name'] = $this->normalizeNameToFqdn($rawName, $domain);

        if (!empty($payload['ttl']))   $params['ttl']   = (int)$payload['ttl'];
        if (!empty($payload['class'])) $params['class'] = $payload['class'];

        // type-specific mapping
        switch ($type) {
            case 'A':
            case 'AAAA':
                $params['address'] = $payload['address'] ?? $payload['content'] ?? null;
                break;

            case 'CNAME':
                $params['cname'] = $payload['cname'] ?? $payload['content'] ?? null;
                break;

            case 'DNAME':
                $params['target'] = $payload['target'] ?? $payload['content'] ?? null;
                break;

            case 'TXT':
                $params['txtdata'] = $payload['txtdata'] ?? $payload['content'] ?? null;
                break;

            case 'MX':
                $params['exchange'] = $payload['exchange'] ?? $payload['content'] ?? null;
                $params['preference'] = (int)($payload['preference'] ?? 0);
                break;

            case 'NS':
                $params['nsdname'] = $payload['nsdname'] ?? $payload['content'] ?? null;
                break;

            case 'PTR':
                $params['ptrdname'] = $payload['ptrdname'] ?? $payload['content'] ?? null;
                break;

            case 'SRV':
                $params['target']   = $payload['target'] ?? null;
                $params['port']     = (int)($payload['port'] ?? 0);
                $params['priority'] = (int)($payload['priority'] ?? 0);
                $params['weight']   = (int)($payload['weight'] ?? 0);
                break;

            case 'CAA':
                $params['flag']  = (int)($payload['flag'] ?? 0);
                $params['tag']   = $payload['tag'] ?? 'issue';
                $params['value'] = $payload['value'] ?? null;
                break;

            case 'AFSDB':
                $params['subtype']  = (int)($payload['subtype'] ?? 1);
                $params['hostname'] = $payload['hostname'] ?? null;
                break;

            case 'DS':
                $params['keytag']     = (int)($payload['keytag'] ?? 0);
                $params['algorithm']  = (int)($payload['algorithm'] ?? 0);
                $params['digesttype'] = (int)($payload['digesttype'] ?? 0);
                $params['digest']     = $payload['digest'] ?? null;
                break;

            case 'HINFO':
                $params['cpu'] = $payload['cpu'] ?? null;
                $params['os']  = $payload['os'] ?? null;
                break;

            case 'LOC':
                $params['location'] = $payload['location'] ?? $payload['content'] ?? null;
                break;

            case 'NAPTR':
                $params['order']       = (int)($payload['order'] ?? 0);
                $params['preference']  = (int)($payload['preference'] ?? 0);
                $params['flags']       = $payload['flags'] ?? '';
                $params['service']     = $payload['service'] ?? '';
                $params['regexp']      = $payload['regexp'] ?? '';
                $params['replacement'] = $payload['replacement'] ?? '.';
                break;

            case 'RP':
                $params['mbox']     = $payload['mbox'] ?? null;
                $params['txtdname'] = $payload['txtdname'] ?? null;
                break;

            default:
                return ['ok' => false, 'error' => "Bu kayıt türü desteklenmiyor: {$type}"];
        }

        // Boş kalmış zorunlu alan kontrolü
        foreach ($params as $k => $v) {
            if ($v === null) {
                return ['ok' => false, 'error' => "Eksik alan: {$k}"];
            }
        }

        return $this->whmApiCall($serverId, 'addzonerecord', $params, 'POST');
    }

    /**
     * Kayıt sil (removezonerecord)
     * WHM API: removezonerecord - line parametresi zorunlu
     */
    public function deleteZoneRecordFromWhm(int $serverId, string $domain, int $line): array
    {
        if ($line <= 0) {
            return ['ok' => false, 'error' => 'Line numarası eksik veya geçersiz.'];
        }

        $params = [
            'domain' => $domain,
            'line'   => $line,
        ];

        return $this->whmApiCall($serverId, 'removezonerecord', $params, 'POST');
    }
}
