<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Mycase extends CI_Controller
{
    private $authUrl  = "https://auth.mycase.com/login_sessions/new";
    private $tokenUrl = "https://auth.mycase.com/tokens";

    public function __construct()
    {
        parent::__construct();
        $autoload['helper'] = array('url');
        $this->load->helper('url');
        $this->load->library('FirebaseLib');
    }

    public function index()
    {
        $this->load->view('mycase_connect');
    }

    // Step 1: Start OAuth flow
    public function connect_start()
    {
        $clientId     = $this->input->post('client_id');
        $clientSecret = $this->input->post('client_secret');
        $redirectUri  = $this->input->post('redirect_uri');
        $lawId  = $this->input->post('lawId');



        if (!$clientId || !$clientSecret || !$redirectUri) $this->showError('Missing required fields!');


        $state = bin2hex(random_bytes(16));

        // Store client credentials in Firebase temp collection (optional)
        $db = $this->firebaselib->getFirestore();
        $db->collection('mycase_oauth_state')->document($state)->set([
            'lawId' => $lawId,
            'client_id'     => $clientId,
            'client_secret' => $clientSecret,
            'redirect_uri'  => $redirectUri,
            'created_at'    => round(microtime(true) * 1000)
        ]);

        $url = $this->authUrl . "?" . http_build_query([
            'response_type' => 'code',
            'client_id'     => $clientId,
            'redirect_uri'  => $redirectUri,
            'scope'         => 'read write',
            'state'         => $state,
            'lawId'         => $lawId
        ]);

        redirect($url);
    }

    // Step 2: Callback after login → exchange code for tokens
    public function access()
    {
        $code  = $this->input->get('code');
        $state = $this->input->get('state');
        $lawId = $this->input->get('lawId');

        // if (!$code || !$state) die(" Authorization failed!");
        if (!$code || !$state) $this->showError('Authorization failed!');


        // Retrieve client credentials from Firebase
        $db = $this->firebaselib->getFirestore();
        $doc = $db->collection('mycase_oauth_state')->document($state)->snapshot();
        // if (!$doc->exists()) die(" Invalid state!");
        if (!$doc->exists()) $this->showError('Invalid state!');


        $credentials = $doc->data();
        $clientId     = $credentials['client_id'];
        $clientSecret = $credentials['client_secret'];
        // $redirectUri  = $credentials['redirect_uri'];
        $redirectUri  = 'https://sugarfest.online/mycase/access.php';


        $tokens = $this->requestToken([
            'grant_type'    => 'authorization_code',
            'code'          => $code,
            'redirect_uri'  => $redirectUri,
            'client_id'     => $clientId,
            'client_secret' => $clientSecret
        ]);

        // if (!isset($tokens['access_token'])) die(" Failed to get tokens");
        if (!isset($tokens['access_token'])) $this->showError('Failed to get access tokens.');


        $currentMs = round(microtime(true) * 1000);

        $db->collection('mycase_tokens')->document($lawId)->set([
            'access_token'  => $tokens['access_token'],
            'refresh_token' => $tokens['refresh_token'],
            'expires_at'    => $currentMs + ($tokens['expires_in'] * 1000), // ms
            'created_at'    => $currentMs
        ]);

        redirect(base_url('mycase/success'));
    }

    private function requestToken($data)
    {
        $ch = curl_init($this->tokenUrl);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($data),
            CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"]
        ]);

        $res = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $json = json_decode($res, true);

        // If server returns HTTP 400/401 or error key exists
        if ($httpCode >= 400 || isset($json['error'])) {
            $errorDesc = $json['error_description'] ?? $json['error'] ?? 'Unknown error';
            $this->showError("Failed to get token: {$errorDesc}");
        }

        return $json;
    }


    public function getAccessToken($userId = 'attorney_123')
    {
        $db = $this->firebaselib->getFirestore();
        $doc = $db->collection('mycase_tokens')->document($userId)->snapshot();

        // No token stored
        if (!$doc->exists()) {
            $this->showError('No token found for this user.');
            return;
        }

        $tokenData = $doc->data();
        $currentMs = round(microtime(true) * 1000);

        $accessToken = $tokenData['access_token'] ?? null;
        $expiresAt   = $tokenData['expires_at'] ?? 0;

        // Token exists and not expired
        if ($accessToken && $currentMs < $expiresAt) {
            echo json_encode(['access_token' => $accessToken]);
            return;
        }

        // Token missing, null, or expired → try refresh
        $refreshToken = $tokenData['refresh_token'] ?? null;

        if (!$refreshToken) {
            $this->showError('No refresh token available to renew access token.');
            return;
        }

        // Request new token using refresh token
        $tokens = $this->requestToken([
            'grant_type'    => 'refresh_token',
            'refresh_token' => $refreshToken,
            'client_id'     => $tokenData['client_id'] ?? '',
            'client_secret' => $tokenData['client_secret'] ?? ''
        ]);

        if (!isset($tokens['access_token'])) {
            $this->showError('Failed to refresh access token.');
            return;
        }

        // Save refreshed token to Firebase
        $db->collection('mycase_tokens')->document($userId)->set([
            'access_token'  => $tokens['access_token'],
            'refresh_token' => $tokens['refresh_token'],
            'expires_at'    => $currentMs + ($tokens['expires_in'] * 1000),
            'updated_at'    => $currentMs
        ]);

        // Return refreshed token
        echo json_encode(['access_token' => $tokens['access_token']]);
    }



    public function success()
    {
        $this->load->view('mycase_success');
    }

    private function showError($message)
    {

        $data = ['message' => $message];
        $this->load->view('mycase_error', $data);
    }
}
