<script setup lang="ts">
import { computed, ref, watch } from 'vue'

import { adminAssignUnit, getUnits } from '@/api/units'
import { getAllRanks } from '@/api/rank'
import { Button } from '@/components/ui/button'
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog'
import { Field, FieldError, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select'
import MemberCard from './MemberCard.vue'
import type { Member } from '@shared/types/member'
import type { Rank } from '@shared/types/rank'
import type { Unit } from '@shared/types/units'

const props = defineProps<{
    open: boolean
    member: Member | null
}>()

const emit = defineEmits<{
    'update:open': [value: boolean]
    transferred: [value: { memberId: number; unitId: number; rankId: number; reason: string }]
}>()

const units = ref<Unit[]>([])
const ranks = ref<Rank[]>([])
const loadingUnits = ref(false)
const loadingRanks = ref(false)
const submitting = ref(false)
const formError = ref('')

const selectedUnitId = ref('')
const selectedRankId = ref('')
const selectedReason = ref('transfer_request')
const customReason = ref('')

const reasonOptions = [
    { label: 'Transfer Request', value: 'transfer_request' },
    { label: 'Leadership Vote', value: 'leadership_vote' },
    { label: 'Appointment', value: 'appointment' },
    { label: 'Step Down', value: 'step_down' },
    { label: 'Custom', value: 'custom' },
]

const resolvedReason = computed(() => {
    if (selectedReason.value === 'custom') {
        return customReason.value.trim()
    }
    return selectedReason.value
})

const canSubmit = computed(() => {
    return !!props.member && !!selectedUnitId.value && !!selectedRankId.value && !!resolvedReason.value
})

function resolveDefaultRankId(member: Member | null): string {
    if (!member || !member.rank) {
        return ''
    }

    const normalizedMemberRank = member.rank.trim().toLowerCase()
    const matchedRank = ranks.value.find((rank) => {
        return rank.name.trim().toLowerCase() === normalizedMemberRank
            || rank.short_name.trim().toLowerCase() === normalizedMemberRank
    })

    return matchedRank ? String(matchedRank.id) : ''
}

function resetForm() {
    selectedUnitId.value = ''
    selectedRankId.value = ''
    selectedReason.value = 'transfer_request'
    customReason.value = ''
    formError.value = ''
}

async function loadUnits() {
    loadingUnits.value = true
    formError.value = ''
    try {
        units.value = await getUnits()
    } catch {
        formError.value = 'Failed to load units. Please try again.'
    } finally {
        loadingUnits.value = false
    }
}

async function loadRanks() {
    loadingRanks.value = true
    formError.value = ''
    try {
        ranks.value = await getAllRanks()
        selectedRankId.value = resolveDefaultRankId(props.member)
    } catch {
        formError.value = 'Failed to load ranks. Please try again.'
    } finally {
        loadingRanks.value = false
    }
}

watch(
    () => props.open,
    (isOpen) => {
        if (isOpen) {
            resetForm()
            loadUnits()
            loadRanks()
        }
    },
)

async function onSubmit() {
    if (!props.member) {
        return
    }

    if (!selectedUnitId.value) {
        formError.value = 'Please select a target unit.'
        return
    }

    if (!selectedRankId.value) {
        formError.value = 'Please select a target rank.'
        return
    }

    if (!resolvedReason.value) {
        formError.value = 'Please select a reason or enter a custom reason.'
        return
    }

    submitting.value = true
    formError.value = ''
    try {
        const unitId = Number(selectedUnitId.value)
        const rankId = Number(selectedRankId.value)
        await adminAssignUnit(props.member.member_id, unitId, rankId, resolvedReason.value)

        emit('transferred', {
            memberId: props.member.member_id,
            unitId,
            rankId,
            reason: resolvedReason.value,
        })
        emit('update:open', false)
    } catch {
        formError.value = 'Failed to transfer member. Please try again.'
    } finally {
        submitting.value = false
    }
}
</script>

<template>
    <Dialog :open="open" @update:open="emit('update:open', $event)">
        <DialogContent class="sm:max-w-[425px]">
            <DialogHeader>
                <DialogTitle>Transfer Member</DialogTitle>
                <DialogDescription>
                    Select a new unit assignment for
                    <MemberCard v-if="member" :member-id="member.member_id" />
                </DialogDescription>
            </DialogHeader>

            <form id="transferForm" @submit.prevent="onSubmit" class="space-y-4 py-2">
                <Field>
                    <FieldLabel>Target Unit</FieldLabel>
                    <Select v-model="selectedUnitId" :disabled="loadingUnits || submitting">
                        <SelectTrigger>
                            <SelectValue placeholder="Select unit" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem v-for="unit in units" :key="unit.id" :value="String(unit.id)">
                                {{ unit.name }}
                            </SelectItem>
                        </SelectContent>
                    </Select>
                </Field>

                <Field>
                    <FieldLabel>Target Rank</FieldLabel>
                    <Select v-model="selectedRankId" :disabled="loadingRanks || submitting">
                        <SelectTrigger>
                            <SelectValue placeholder="Select rank" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem v-for="rank in ranks" :key="rank.id" :value="String(rank.id)">
                                {{ rank.name }}
                            </SelectItem>
                        </SelectContent>
                    </Select>
                </Field>

                <Field>
                    <FieldLabel>Reason</FieldLabel>
                    <Select v-model="selectedReason" :disabled="submitting">
                        <SelectTrigger>
                            <SelectValue placeholder="Select reason" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem
                                v-for="reason in reasonOptions"
                                :key="reason.value"
                                :value="reason.value"
                            >
                                {{ reason.label }}
                            </SelectItem>
                        </SelectContent>
                    </Select>
                </Field>

                <Field v-if="selectedReason === 'custom'">
                    <FieldLabel>Custom Reason</FieldLabel>
                    <Input
                        v-model="customReason"
                        :disabled="submitting"
                        placeholder="Enter custom transfer reason"
                    />
                </Field>

                <FieldError v-if="formError" :errors="[formError]" />
            </form>

            <DialogFooter class="gap-2">
                <Button variant="ghost" @click="emit('update:open', false)">
                    Cancel
                </Button>
                <Button type="submit" form="transferForm" :disabled="!canSubmit || loadingUnits || loadingRanks || submitting">
                    {{ submitting ? 'Transferring...' : 'Transfer Member' }}
                </Button>
            </DialogFooter>
        </DialogContent>
    </Dialog>
</template>