<script setup lang="ts">
import { Trash2, Copy, Clipboard, Check } from '@lucide/vue';
import { computed, ref } from 'vue';
import { NumberInput } from '@/components/form/number-input';
import { RupiahInput } from '@/components/form/rupiah-input';
import MediaDropzone from '@/components/media/MediaDropzone.vue';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Field,
    FieldError,
    FieldGroup,
    FieldLabel,
    FieldSet,
} from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { useCan } from '@/composables/useCan';
import { FIELD_LIMITS } from '@/lib/field-limits';
import type { MediaUploadState } from '@/types/media';
import { PRICE_TYPES, PRICE_TYPE_LABELS } from '@/types/product';
import type { ProductVariantFormItem } from '@/types/product';

const { hasRole } = useCan();
const showPrices = computed(() => props.showPrices ?? !hasRole('admin-bahan-baku'));

const props = defineProps<{
    form: {
        errors: Record<string, string>;
    };
    variant: ProductVariantFormItem;
    index: number;
    canRemove: boolean;
    hasCopiedPrices: boolean;
    showPrices?: boolean;
    variantErrors: (clientId: string, field: string) => string[];
}>();

const emit = defineEmits<{
    remove: [];
    'update:name': [value: string];
    'update:stock': [value: string];
    'update:retail-stock': [value: string];
    'update:prices': [value: Record<string, string>];
    'update:media': [value: MediaUploadState];
    'copy-prices': [];
    'paste-prices': [];
    'apply-to-all-prices': [];
}>();

const isCopied = ref(false);
const isPasted = ref(false);
const isApplied = ref(false);

function handleCopy() {
    emit('copy-prices');
    isCopied.value = true;
    setTimeout(() => {
        isCopied.value = false;
    }, 2000);
}

function handlePaste() {
    emit('paste-prices');
    isPasted.value = true;
    setTimeout(() => {
        isPasted.value = false;
    }, 2000);
}

function handleApply() {
    emit('apply-to-all-prices');
    isApplied.value = true;
    setTimeout(() => {
        isApplied.value = false;
    }, 2000);
}

function updatePrice(type: string, value: string) {
    const updatedPrices = {
        ...(props.variant.prices as Record<string, string> || {}),
        [type]: value,
    };
    emit('update:prices', updatedPrices);
}
</script>

<template>
    <Card>
        <CardHeader class="flex flex-row items-start justify-between gap-4">
            <CardTitle>Varian {{ index + 1 }}</CardTitle>
            <Button v-if="canRemove" type="button" variant="outline" size="icon"
                class="text-destructive hover:text-destructive size-8" @click="emit('remove')">
                <Trash2 class="size-4" />
            </Button>
        </CardHeader>
        <CardContent>
            <FieldGroup>
                <FieldSet class="grid gap-4 md:grid-cols-3">
                    <Field>
                        <FieldLabel :for="`variant_name_${variant.client_id}`" required>
                            Nama Varian
                        </FieldLabel>
                        <Input :id="`variant_name_${variant.client_id}`" :model-value="variant.name" type="text"
                            placeholder="Masukkan nama varian" :maxlength="FIELD_LIMITS.variantName"
                            @update:model-value="emit('update:name', String($event))" />
                        <FieldError :errors="variantErrors(variant.client_id, 'name')" />
                    </Field>
                    <Field>
                        <FieldLabel :for="`variant_stock_${variant.client_id}`" required>
                            Stok
                        </FieldLabel>
                        <NumberInput :id="`variant_stock_${variant.client_id}`" :model-value="variant.stock"
                            @update:model-value="emit('update:stock', String($event))" />
                        <FieldError :errors="variantErrors(variant.client_id, 'stock')" />
                    </Field>
                    <Field>
                        <FieldLabel :for="`variant_retail_stock_${variant.client_id}`" required>
                            Stok Ecer
                        </FieldLabel>
                        <NumberInput :id="`variant_retail_stock_${variant.client_id}`"
                            :model-value="variant.retail_stock"
                            @update:model-value="emit('update:retail-stock', String($event))" />
                        <FieldError :errors="variantErrors(variant.client_id, 'retail_stock')" />
                    </Field>
                </FieldSet>

                <div v-if="showPrices" class="border-t pt-4 mt-2">
                    <div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between mb-3">
                        <h4 class="text-sm font-semibold">Harga Varian</h4>
                        <div class="flex flex-wrap items-center gap-2">
                            <Button type="button" variant="outline" size="sm"
                                class="h-8 px-2.5 text-xs flex items-center gap-1.5" @click="handleCopy">
                                <Check v-if="isCopied"
                                    class="size-3.5 text-green-600 animate-in fade-in zoom-in-50 duration-200" />
                                <Copy v-else class="size-3.5" />
                                {{ isCopied ? 'Berhasil' : 'Salin Harga' }}
                            </Button>
                            <Button type="button" variant="outline" size="sm"
                                class="h-8 px-2.5 text-xs flex items-center gap-1.5" :disabled="!hasCopiedPrices"
                                @click="handlePaste">
                                <Check v-if="isPasted"
                                    class="size-3.5 text-green-600 animate-in fade-in zoom-in-50 duration-200" />
                                <Clipboard v-else class="size-3.5" />
                                {{ isPasted ? 'Berhasil' : 'Tempel Harga' }}
                            </Button>
                            <Button type="button" variant="outline" size="sm"
                                class="h-8 px-2.5 text-xs flex items-center gap-1.5" @click="handleApply">
                                <Check v-if="isApplied"
                                    class="size-3.5 text-green-600 animate-in fade-in zoom-in-50 duration-200" />
                                <Check v-else class="size-3.5" />
                                {{ isApplied ? 'Berhasil' : 'Terapkan ke Semua' }}
                            </Button>
                        </div>
                    </div>
                    <div class="grid gap-3 grid-cols-2 md:grid-cols-4">
                        <Field v-for="type in PRICE_TYPES" :key="`${variant.client_id}-${type}`">
                            <FieldLabel class="text-xs" :for="`variant_price_${variant.client_id}_${type}`" required>
                                {{ PRICE_TYPE_LABELS[type] }}
                            </FieldLabel>
                            <RupiahInput :id="`variant_price_${variant.client_id}_${type}`"
                                :model-value="(variant.prices as Record<string, string>)?.[type] ?? '0'"
                                @update:model-value="updatePrice(type, $event)" />
                            <FieldError :errors="variantErrors(variant.client_id, `prices.${type}`)" />
                        </Field>
                    </div>
                </div>

                <div>
                    <MediaDropzone :id="`variant_images_${variant.client_id}`" :model-value="variant.media"
                        label="Foto Varian" :max-files="5" required :errors="variantErrors(variant.client_id, 'images')"
                        @update:model-value="emit('update:media', $event)" />
                </div>
            </FieldGroup>
        </CardContent>
    </Card>
</template>
