<?php

namespace Wave\Http\Controllers\CMS;

use App\Http\Controllers\Controller;
use App\Models\BookkeepingDocument;
use App\Models\BookkeepingDocumentCategory;
use App\Models\Company;
use App\Models\DocumentActionLogs;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Yajra\DataTables\Facades\DataTables;

class BookkeepingController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        return view('theme::cms.bookkeepings.index');
    }
    
    public function getCompanies()
    {
        $nameColumn = strtolower(app()->getLocale()) == 'zh_hk' ? 'name_chinese' : 'name_english';
        $companies = Company::where($nameColumn, '!=', null)
            ->orderBy($nameColumn)
            ->get()
            ->map(function ($company) use ($nameColumn) {
                $company->name = $company->{$nameColumn};
                
                return $company;
            });

        return response()->json([
            'success' => true,
            'companies' => $companies,
        ]);
    }
    
    public function getCategories()
    {
        $categories = BookkeepingDocumentCategory::where('status', 'active')
            ->orderBy('name')
            ->get();

        return response()->json([
            'success' => true,
            'categories' => $categories,
        ]);
    }

    public function table($isCompleted = false)
    {
        $documents = BookkeepingDocument::query()
            ->select(
                'bookkeeping_documents.id',
                'companies.name_english',
                'companies.name_chinese',
                'bookkeeping_documents.file_name',
                'bookkeeping_document_categories.name as category_name',
                'users.first_name',
                'users.last_name',
                'bookkeeping_documents.batch_name',
                'bookkeeping_documents.remark',
                'bookkeeping_documents.created_at',
                'bookkeeping_documents.status',
                'bookkeeping_documents.xero_status',
                'bookkeeping_documents.xero_amount',
            )
            ->leftJoin('companies', 'bookkeeping_documents.company_id', '=', 'companies.id')
            ->leftJoin('users', 'bookkeeping_documents.user_id', '=', 'users.id')
            ->leftJoin('bookkeeping_document_categories', 'bookkeeping_documents.bookkeeping_document_category_id', '=', 'bookkeeping_document_categories.id');

        if ($isCompleted) {
            $documents = $documents->where('bookkeeping_documents.status', 'completed');
        }
        else {
            $documents = $documents->where('bookkeeping_documents.status', '!=', 'completed');
        }

        $processCount = $documents->clone()->where('bookkeeping_documents.status', 'in_progress')->count();
        $queueCount = $documents->clone()->where('bookkeeping_documents.status', 'uploaded')->count();

        return Datatables::of($documents)
            ->escapeColumns(['id'])
            ->addColumn('file_name', function ($document) {
                $ext = pathinfo($document->file_name, PATHINFO_EXTENSION);

                return '
                    <div class="flex justify-start">
                        <img class="max-25" src="' . ( $ext == 'pdf' ? asset('themes/tailwind/images/pdf.svg') : asset('themes/tailwind/images/jpg.svg')) . '">
                        <span class="fix-text">' . $document->file_name . '</span>
                    </div>
                ';
            })
            ->addColumn('user_name', function ($document) {
                if ($document->status == 'uploaded') {
                    return '<span class="grey-text">processing...</span>';
                }
                else if ($document->status == 'failed') {
                    return '<span class="grey-text" style="color: #6D7581;">Failed</span>';
                }

                return $document->first_name . ($document->last_name ? ' ' : '') . $document->last_name;
            })
            ->addColumn('created_at', function ($document) {
                return date('Ymd-H:i', strtotime($document->created_at));
            })
            ->addColumn('status_select', function ($document) {
                $html = '
                    <select class="change-status" data-id="' . $document->id . '">
                        <option value="uploaded" ' . ($document->status == 'uploaded' ? 'selected' : '') . '>' . __("Uploaded") . '</option>
                        <option value="in_progress" ' . ($document->status == 'in_progress' ? 'selected' : '') . '>' . __("In Progress") . '</option>
                        <option value="ocr_complete" ' . ($document->status == 'ocr_complete' ? 'selected' : '') . '>' . __("OCR Completed") . '</option>
                        <option value="failed" ' . ($document->status == 'failed' ? 'selected' : '') . '>' . __("Failed") . '</option>
                        <option value="completed" ' . ($document->status == 'completed' ? 'selected' : '') . '>' . __("Completed") . '</option>
                    </select>
                ';

                if ($document->status == 'failed') {
                    $html .= '
                        <div>
                            <input type="file" data-id="' . $document->id . '" class="d-none re-upload-file" accept="image/png, image/jpeg, application/pdf, application/msword" multiple>
                            <button type="button" class="failed item-list-note flex btn-link reupload-button" style="text-wrap: nowrap;">
                                <img class="max-25" src="' . asset('themes/tailwind/images/flag-2.svg') . '"> ' . __("Reupload") . '
                            </button>
                        </div>';
                }
                else if ($document->status == 'ocr_complete') {
                    $html .= '<button type="button" class="failed item-list-note flex btn-link" style="text-wrap: nowrap;"><img class="max-25" src="' . asset('themes/tailwind/images/flag-2.svg') . '"> ' . __("Require Datamolino") . '?</button>';
                }

                return $html;
            })
            ->addColumn('xero_status', function ($document) {
                if ($document->status != 'ocr_complete') {
                    if ($document->xero_status) {
                        return '<img class="max-25" src="' . asset("themes/tailwind/images/success.svg") . '">';
                    }
                    else {
                        return '<img class="max-25" src="' . asset("themes/tailwind/images/error.svg") . '">';
                    }
                }

                return '';
            })
            ->addColumn('xero_amount', function ($document) {
                if ($document->xero_amount > 0 && $document->status != 'ocr_complete') {
                    return '$' . $document->xero_amount;
                }

                return '';
            })
            ->addColumn('actions', function ($document) {
                $actions = '
                    <div class="dropdown non-custom">
                        <button type="button" data-bs-toggle="dropdown" aria-expanded="false"><img class="max-25" src="' . asset('themes/tailwind/images/more.svg') . '"></button>
                        <div class="dropdown-menu">
                            <a class="dropdown-item" href="#">' . __("Cancel Request") . '</a>
                            <a class="dropdown-item" href="#">' . __("Message on file") . '</a>
                            <a class="dropdown-item" href="#">' . __("Stop processing") . '</a>
                        </div>
                    </div>
                ';
                return $actions;
            })
            ->with([
                'processCount' => $processCount,
                'queueCount' => $queueCount,
            ])
            ->make(true);
    }

    public function updateStatus(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required',
            'status' => 'required',
            'xero_status' => [
                'nullable',
                Rule::requiredIf($request->status == 'completed'),
            ],
            'xero_amount' => [
                'nullable',
                Rule::requiredIf($request->status == 'completed'),
                'numeric',
            ],
        ]);
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }
        else {
            $bookkeepingDocument = BookkeepingDocument::find($request->id);
            if (! $bookkeepingDocument) {
                return response()->json([
                    'success' => false,
                    'message' => __("Document not exists!"),
                ]);
            }
            $bookkeepingDocument->status = $request->status;
            if ($request->status == 'completed') {
                $bookkeepingDocument->xero_status = $request->xero_status == '1' ? true : false;
                $bookkeepingDocument->xero_amount = $request->xero_amount;
            }
            $bookkeepingDocument->save();

            DocumentActionLogs::create([
                'user_id' => $request->user()->id,
                'event' => 'Change status',
                'description' => 'Change [' . $bookkeepingDocument->file_name . '] status to ' . $request->status . '.',
                'status' => 'success',
            ]);
            
            if ($request->status == 'completed') {
                storeUserNotification(null, 'Bookkeeping Queue', $bookkeepingDocument->file_name, 'Bookkeeping Queue', true, $bookkeepingDocument->id, 'bookkeeping_queue', 'completed');
            }
            else if ($request->status == 'failed') {
                storeUserNotification(null, 'Bookkeeping Queue', $bookkeepingDocument->file_name, 'Bookkeeping Queue', true, $bookkeepingDocument->id, 'bookkeeping_queue', 'failed');
            }
    
            return response()->json([
                'success' => true,
                'message' => __("Document has successfully updated!"),
            ]);
        }
    }

    public function actionLogsTable()
    {
        $logs = DocumentActionLogs::query()
            ->select(
                'users.email',
                'users.name',
                'document_action_logs.created_at',
                'document_action_logs.event',
                'document_action_logs.description',
                'document_action_logs.status',
            )
            ->leftJoin('users', 'document_action_logs.user_id', '=', 'users.id');

        return Datatables::of($logs)
            ->escapeColumns(['id'])
            ->addColumn('date', function ($log) {
                return date('Ymd', strtotime($log->created_at));
            })
            ->addColumn('time', function ($log) {
                return date('H:i', strtotime($log->created_at));
            })
            ->addColumn('status', function ($log) {
                return '<span class="' . $log->status . ' item-list-note">' . ucwords($log->status) . '</span>';
            })
            ->make(true);
    }

    public function reUploadFile(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required',
            'uploaded_file' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }
        else {
            $bookkeepingDocument = BookkeepingDocument::find($request->id);
            if (! $bookkeepingDocument) {
                return response()->json([
                    'success' => true,
                    'message' => __("Document not exists!"),
                ]);
            }

            $fileName = '';
            if ($request->hasFile('uploaded_file')) {
                if (\Storage::exists($bookkeepingDocument->file_path)) {
                    \Storage::delete($bookkeepingDocument->file_path);
                }

                $file = $request->file('uploaded_file');
                $fileName = $request->file('uploaded_file')->getClientOriginalName();
                $file->storePubliclyAs($bookkeepingDocument->folder_path, $fileName);

                $bookkeepingDocument->file_name = $fileName;
                $bookkeepingDocument->status = 'uploaded';
                $bookkeepingDocument->save();
            }

            DocumentActionLogs::create([
                'user_id' => $request->user()->id,
                'event' => 'Upload',
                'description' => 'Upload [' . $fileName . '] from local file.',
                'status' => 'success',
            ]);
    
            return response()->json([
                'success' => true,
                'message' => __("Document has successfully uploaded!"),
            ]);
        }
    }
}
