<template>
	<Dialog
		v-model="open"
		:options="{
			title: 'Access Request',
			actions,
		}"
	>
		<template #body-content>
			<div class="space-y-4 text-base">
				<div
					v-if="banner"
					class="py-3 px-4 font-medium rounded border"
					:class="{
						'bg-green-50 border-green-200 text-green-800':
							banner.type === 'success',
						'bg-red-50 border-red-200 text-red-800': banner.type === 'error',
						'bg-gray-50 border-gray-200 text-gray-800':
							banner.type === 'neutral',
					}"
				>
					{{ banner.message }}
				</div>
				<p v-if="isReceived && isPending" class="leading-normal">
					Do you want to accept or reject this access request?
				</p>
				<div class="rounded-sm border divide-y">
					<div
						v-for="resource in request.pg?.resources"
						class="grid grid-cols-3 divide-x"
					>
						<div class="col-span-1 py-2 px-3 font-medium">
							{{ resource.document_type }}
						</div>
						<div class="col-span-2 py-2 px-3">
							<Link
								:to="
									resourceLink(resource.document_type, resource.document_name)
								"
								@click="
									() =>
										resourceLink(
											resource.document_type,
											resource.document_name,
										) && (open = false)
								"
							>
								{{ resource.document_name }}
							</Link>
						</div>
					</div>
				</div>
				<div v-if="request.pg?.reason" class="space-y-2">
					<p class="font-medium">Reason:</p>
					<p class="leading-relaxed">{{ request.pg?.reason }}</p>
				</div>
				<div v-if="permissions.length" class="space-y-2">
					<p class="font-medium">Permissions:</p>
					<div class="flex flex-wrap gap-2">
						<Badge
							v-for="permission in permissions"
							variant="outline"
							:theme="permission.color"
							size="lg"
						>
							{{ permission.label }}
						</Badge>
					</div>
				</div>
			</div>
		</template>
	</Dialog>
</template>

<script setup lang="ts">
import Link from './Link.vue';
import { Badge, createDocumentResource, createResource } from 'frappe-ui';
import { computed, ref } from 'vue';
import { getTeam } from '../data/team';
import { toast } from 'vue-sonner';

const props = defineProps<{
	name: string;
}>();

const open = ref(true);
const team = getTeam();

const request = createDocumentResource({
	doctype: 'Support Access',
	name: props.name,
	auto: true,
});

const isReceived = computed(() => {
	return team.pg?.name === request.pg?.target_team;
});

const isPending = computed(() => {
	return request.pg?.status === 'Pending';
});

const permissions = computed(() =>
	[
		{
			label: 'Release Group',
			requested: request.pg?.site_release_group,
			color: 'red',
		},
		{
			label: 'SSH',
			requested: request.pg?.bench_ssh,
			color: 'red',
		},
		{
			label: 'Login as Administrator',
			requested: request.pg?.login_as_administrator,
			color: 'orange',
		},
		{
			label: 'Domains',
			requested: request.pg?.site_domains,
			color: 'green',
		},
	].filter((p) => p.requested),
);

const update = createResource({
	url: 'press.api.client.set_value',
	makeParams: (args: any) => ({
		doctype: 'Support Access',
		name: props.name,
		fieldname: {
			status: args.status,
		},
	}),
	onSuccess: (data: any) => {
		toast.success(`Request ${data.status}`);
		open.value = false;
	},
});

const banner = computed(() => {
	if (request.pg?.status === 'Accepted') {
		return {
			type: 'success',
			message: 'This request has been accepted.',
		};
	} else if (request.pg?.status === 'Rejected') {
		return {
			type: 'error',
			message: 'This request has been rejected.',
		};
	} else if (request.pg?.status === 'Revoked') {
		return {
			type: 'neutral',
			message: 'This request has been revoked.',
		};
	} else if (request.pg?.status === 'Forfeited') {
		return {
			type: 'neutral',
			message: 'This request has been forfeited.',
		};
	}
});

const actions = computed(() => {
	const actions = [];
	const isExpired = new Date(request.pg.access_allowed_till) < new Date();

	if (request.pg?.status === 'Pending' && isReceived.value) {
		actions.push(
			{
				label: 'Reject',
				variant: 'subtle',
				theme: 'red',
				onClick: () => {
					update.submit({
						status: 'Rejected',
					});
				},
			},
			{
				label: 'Accept',
				variant: 'solid',
				onClick: () => {
					update.submit({
						status: 'Accepted',
					});
				},
			},
		);
	}

	if (request.pg?.status === 'Accepted' && isReceived.value && !isExpired) {
		actions.push({
			label: 'Revoke',
			variant: 'subtle',
			theme: 'red',
			onClick: () => {
				update.submit({
					status: 'Revoked',
				});
			},
		});
	}

	if (request.pg?.status === 'Accepted' && !isReceived.value && !isExpired) {
		actions.push({
			label: 'Forfeit',
			variant: 'subtle',
			theme: 'red',
			onClick: () => {
				update.submit({
					status: 'Forfeited',
				});
			},
		});
	}

	return actions;
});

const resourceLink = (documentType: string, documentName: string) => {
	switch (documentType) {
		case 'Site':
			return {
				name: 'Site Detail',
				params: {
					name: documentName,
				},
			};
		case 'Release Group':
			return {
				name: 'Release Group Detail',
				params: {
					name: documentName,
				},
			};
		case 'Bench':
			return {
				name: 'Bench Detail',
				params: {
					name: documentName,
				},
			};
	}
};
</script>
