//go:build darwin

package main

/*
#cgo CFLAGS: -x objective-c -fobjc-arc -fblocks
#cgo LDFLAGS: -framework AppKit -framework QuartzCore
#include <stdlib.h>
#include <dispatch/dispatch.h>
#import <AppKit/AppKit.h>
#import <QuartzCore/QuartzCore.h>

static NSPanel *operationPanel = nil;
static NSTextField *operationTitleLabel = nil;
static NSTextField *operationDetailLabel = nil;
static NSTextField *operationIconLabel = nil;
static NSProgressIndicator *operationSpinner = nil;

static NSString *statusString(const char *value) {
    if (value == NULL) {
        return @"";
    }
    NSString *text = [NSString stringWithUTF8String:value];
    return text ?: @"";
}

static void ensureOperationPanel(void) {
    if (operationPanel != nil) {
        return;
    }

    NSRect frame = NSMakeRect(0, 0, 360, 118);
    operationPanel = [[NSPanel alloc]
        initWithContentRect:frame
                  styleMask:NSWindowStyleMaskBorderless
                    backing:NSBackingStoreBuffered
                      defer:NO];
    [operationPanel setOpaque:NO];
    [operationPanel setBackgroundColor:[NSColor clearColor]];
    [operationPanel setLevel:NSFloatingWindowLevel];
    [operationPanel setHidesOnDeactivate:NO];
    [operationPanel setCollectionBehavior:
        NSWindowCollectionBehaviorCanJoinAllSpaces |
        NSWindowCollectionBehaviorFullScreenAuxiliary |
        NSWindowCollectionBehaviorStationary];

    NSView *root = [[NSView alloc] initWithFrame:frame];
    [root setWantsLayer:YES];
    [[root layer] setCornerRadius:14];
    [[root layer] setBackgroundColor:[[NSColor colorWithCalibratedWhite:0.08 alpha:0.92] CGColor]];
    [[root layer] setShadowColor:[[NSColor blackColor] CGColor]];
    [[root layer] setShadowOpacity:0.28];
    [[root layer] setShadowRadius:18];
    [[root layer] setShadowOffset:CGSizeMake(0, -8)];

    operationSpinner = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(24, 42, 34, 34)];
    [operationSpinner setStyle:NSProgressIndicatorStyleSpinning];
    [operationSpinner setIndeterminate:YES];

    operationIconLabel = [NSTextField labelWithString:@"OK"];
    [operationIconLabel setFrame:NSMakeRect(21, 43, 42, 30)];
    [operationIconLabel setAlignment:NSTextAlignmentCenter];
    [operationIconLabel setFont:[NSFont systemFontOfSize:17 weight:NSFontWeightSemibold]];
    [operationIconLabel setTextColor:[NSColor colorWithCalibratedRed:74.0/255.0 green:222.0/255.0 blue:128.0/255.0 alpha:1.0]];
    [operationIconLabel setHidden:YES];

    operationTitleLabel = [NSTextField labelWithString:@""];
    [operationTitleLabel setFrame:NSMakeRect(76, 61, 260, 24)];
    [operationTitleLabel setFont:[NSFont systemFontOfSize:15 weight:NSFontWeightSemibold]];
    [operationTitleLabel setTextColor:[NSColor whiteColor]];

    operationDetailLabel = [NSTextField labelWithString:@""];
    [operationDetailLabel setFrame:NSMakeRect(76, 34, 260, 22)];
    [operationDetailLabel setFont:[NSFont systemFontOfSize:12 weight:NSFontWeightRegular]];
    [operationDetailLabel setTextColor:[NSColor colorWithCalibratedWhite:0.82 alpha:1.0]];
    [operationDetailLabel setLineBreakMode:NSLineBreakByTruncatingTail];

    [root addSubview:operationSpinner];
    [root addSubview:operationIconLabel];
    [root addSubview:operationTitleLabel];
    [root addSubview:operationDetailLabel];
    [operationPanel setContentView:root];
}

static void snipShowOperationStatus(const char *titleC, const char *detailC, int state) {
    NSString *title = statusString(titleC);
    NSString *detail = statusString(detailC);
    dispatch_async(dispatch_get_main_queue(), ^{
        ensureOperationPanel();
        [operationTitleLabel setStringValue:title];
        [operationDetailLabel setStringValue:detail];

        if (state == 0) {
            [operationIconLabel setHidden:YES];
            [operationSpinner setHidden:NO];
            [operationSpinner startAnimation:nil];
        } else {
            [operationSpinner stopAnimation:nil];
            [operationSpinner setHidden:YES];
            [operationIconLabel setHidden:NO];
            if (state == 2) {
                [operationIconLabel setStringValue:@"!"];
                [operationIconLabel setTextColor:[NSColor colorWithCalibratedRed:248.0/255.0 green:113.0/255.0 blue:113.0/255.0 alpha:1.0]];
            } else {
                [operationIconLabel setStringValue:@"OK"];
                [operationIconLabel setTextColor:[NSColor colorWithCalibratedRed:74.0/255.0 green:222.0/255.0 blue:128.0/255.0 alpha:1.0]];
            }
        }

        NSScreen *screen = [NSScreen mainScreen];
        if (screen != nil) {
            NSRect visible = [screen visibleFrame];
            NSRect panelFrame = [operationPanel frame];
            panelFrame.origin.x = NSMidX(visible) - panelFrame.size.width / 2;
            panelFrame.origin.y = NSMaxY(visible) - panelFrame.size.height - 48;
            [operationPanel setFrame:panelFrame display:YES];
        }
        [operationPanel orderFrontRegardless];
    });
}

static void snipHideOperationStatus(void) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (operationPanel != nil) {
            [operationSpinner stopAnimation:nil];
            [operationPanel orderOut:nil];
        }
    });
}
*/
import "C"

import (
	"sync/atomic"
	"time"
	"unsafe"
)

const (
	operationStatusRunning = iota
	operationStatusSuccess
	operationStatusError
)

var operationStatusSeq atomic.Uint64

func showOperationStatus(title, detail string, state int) {
	operationStatusSeq.Add(1)
	ctitle := C.CString(title)
	cdetail := C.CString(detail)
	defer C.free(unsafe.Pointer(ctitle))
	defer C.free(unsafe.Pointer(cdetail))
	C.snipShowOperationStatus(ctitle, cdetail, C.int(state))
}

func hideOperationStatusAfter(delay time.Duration) {
	seq := operationStatusSeq.Load()
	time.AfterFunc(delay, func() {
		if operationStatusSeq.Load() == seq {
			C.snipHideOperationStatus()
		}
	})
}
