<template>
	<div class="editor">
		<p
			v-if="submitted"
			class="submitted"
		>
			<template v-if="apply">Your revision has been submitted. Thank you for your contribution!</template>
			<template v-else>Your revision has been submitted for review. Thank you for your contribution!</template>

			<ul>
				<li>
					<a
						:href="`/actor/${actor.id}/${actor.slug}`"
						class="link"
					>Return to actor</a>
				</li>

				<li>
					<a
						:href="`/actor/edit/${actor.id}`"
						class="link"
					>Make another edit</a>
				</li>

				<li>
					<a
						:href="`/actor/revs/${actor.id}/${actor.slug}`"
						class="link"
					>Go to actor revisions</a>
				</li>

				<li>
					<a
						:href="`/user/${user.username}/revisions/actors`"
						class="link"
					>Go to user revisions</a>
				</li>

				<li v-if="user.role !== 'user'">
					<a
						href="/admin/revisions/actors"
						class="link"
					>Go to revisions admin</a>
				</li>
			</ul>
		</p>

		<form
			v-else
			@submit.prevent
		>
			<div class="editor-header">
				<h2 class="heading ellipsis">Edit actor #{{ actor.id }} - {{ actor.name }}</h2>

				<a
					:href="`/actor/${actor.id}/${actor.slug}`"
					target="_blank"
					class="link noshrink"
				>Go to actor</a>
			</div>

			<ul class="nolist">
				<li
					v-for="item in fields"
					:key="`item-${item.key}`"
					class="row"
				>
					<div class="item-header">
						<div class="key">{{ item.label || item.key }}</div>

						<div class="item-actions">
							<Icon
								v-if="!item.forced"
								icon="pencil5"
								:class="{ active: editing.has(item.key) }"
								@click="toggleField(item)"
							/>
						</div>
					</div>

					<div
						class="value"
						:class="{ disabled: !editing.has(item.key) }"
					>
						<input
							v-if="item.type === 'string'"
							v-model="edits[item.key]"
							class="string input"
							:list="item.suggestions && `suggestions-${item.key}`"
							:disabled="!editing.has(item.key)"
						>

						<datalist
							v-if="item.suggestions"
							:id="`suggestions-${item.key}`"
						>
							<option
								v-for="(suggestion, index) in item.suggestions"
								:key="`suggestion-${item.key}-${index}`"
							>{{ suggestion }}</option>
						</datalist>

						<textarea
							v-if="item.type === 'text'"
							v-model="edits[item.key]"
							:placeholder="item.placeholder"
							rows="3"
							class="text input"
							:disabled="!editing.has(item.key)"
						/>

						<template v-if="item.type === 'number'">
							<input
								v-model="edits[item.key]"
								type="number"
								:max="item.max"
								:min="item.min"
								class="number input"
								:disabled="!editing.has(item.key)"
							>{{ item.unit }}
						</template>

						<input
							v-if="item.type === 'date'"
							v-model="edits[item.key]"
							type="date"
							class="date input"
							:disabled="!editing.has(item.key)"
						>

						<select
							v-if="item.type === 'select'"
							v-model="edits[item.key]"
							class="select input"
							:disabled="!editing.has(item.key)"
						>
							<option
								v-for="option in item.options"
								:key="`${item.key}-option-${option}`"
								:value="typeof option?.value === 'undefined' ? option : option.value"
							>{{ option?.label || option }}</option>
						</select>

						<div
							v-if="item.type === 'place'"
							class="place"
						>
							<div class="value-section">
								<span class="value-label">Country</span>

								<select
									v-model="edits[item.key].country"
									class="select input"
									placeholder="Country"
									:disabled="!editing.has(item.key)"
								>
									<option
										:key="`${item.key}-country-unknown`"
										:value="null"
									/>

									<option
										v-for="country in sortedCountries"
										:key="`${item.key}-country-${country.alpha2}`"
										:value="country.alpha2"
									>{{ country.alias || country.name }}</option>
								</select>
							</div>

							<div class="value-section">
								<span class="value-label">State</span>

								<input
									v-model="edits[item.key].state"
									class="string input"
									:disabled="!editing.has(item.key)"
								>
							</div>

							<div class="value-section">
								<span class="value-label">City</span>

								<input
									v-model="edits[item.key].city"
									class="string input"
									:disabled="!editing.has(item.key)"
								>
							</div>
						</div>

						<div
							v-if="item.type === 'figure'"
							class="figure"
						>
							<div class="value-section">
								<span class="value-label">Units</span>

								<select
									v-model="figureUnits"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option value="us">USA</option>
									<option value="uk">UK</option>
									<option value="eu">Europe/Asia</option>
									<option value="jp">Japan</option>
									<option value="au">Australia</option>
									<option value="it">Italy</option>
									<option value="fr">France</option>
								</select>
							</div>

							<span class="figure-bust">
								<div class="value-section">
									<span class="value-label">Bust</span>

									<select
										v-model="edits[item.key].bust"
										class="select input"
										placeholder="Bust"
										:disabled="!editing.has(item.key)"
									>
										<option
											:key="`${item.key}-bust-unknown`"
											:value="null"
										/>

										<option
											v-for="bust in bustSizes[figureUnits]"
											:key="`${item.key}-bust-${bust}`"
											:value="Array.isArray(bust) ? bust[0] : bust"
										>{{ Array.isArray(bust) ? bust.join('/') : bust }}</option>
									</select>
								</div>

								<div class="value-section">
									<span class="value-label">Cup</span>

									<select
										v-model="edits[item.key].cup"
										class="select input"
										placeholder="Cup"
										:disabled="!editing.has(item.key)"
									>
										<option
											:key="`${item.key}-cup-unknown`"
											:value="null"
										/>

										<option
											v-for="cup in cupSizes[figureUnits]"
											:key="`${item.key}-cup-${cup}`"
											:value="Array.isArray(cup) ? cup[0] : cup"
										>{{ Array.isArray(cup) ? cup.join('/') : cup }}</option>
									</select>
								</div>
							</span>

							<div class="value-section">
								<span class="value-label">Waist</span>

								<span>
									<input
										v-model="edits[item.key].waist"
										type="number"
										class="input"
										:disabled="!editing.has(item.key)"
									>

									<template v-if="['us', 'uk'].includes(figureUnits)">&nbsp;inch</template>
									<template v-else>&nbsp;cm</template>
								</span>
							</div>

							<div class="value-section">
								<span class="value-label">Hip</span>

								<span>
									<input
										v-model="edits[item.key].hip"
										type="number"
										class="input"
										:disabled="!editing.has(item.key)"
									>

									<template v-if="['us', 'uk'].includes(figureUnits)">&nbsp;inch</template>
									<template v-else>&nbsp;cm</template>
								</span>
							</div>
						</div>

						<div
							v-if="item.type === 'augmentation'"
							class="figure augmentation"
						>
							<div class="value-section">
								<span class="value-label">Natural boobs</span>

								<select
									v-model="edits[item.key].naturalBoobs"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option :value="true">Yes</option>
									<option :value="false">No</option>
								</select>
							</div>

							<div
								v-if="edits[item.key].naturalBoobs === false"
								class="value-section"
							>
								<span class="value-label">Implant CC</span>

								<input
									v-model="edits[item.key].boobsVolume"
									type="number"
									class="volume input"
									placeholder="CC"
									min="50"
									max="10000"
									:disabled="!editing.has(item.key)"
								>
							</div>

							<div
								v-if="edits[item.key].naturalBoobs === false"
								class="value-section"
							>
								<span class="value-label">Implant type</span>

								<select
									v-model="edits[item.key].boobsImplant"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option value="saline">Saline</option>
									<option value="silicone">Silicone</option>
									<option value="gummy">Gummy</option>
									<option value="fat">Fat transfer</option>
								</select>
							</div>

							<div
								v-if="edits[item.key].naturalBoobs === false"
								class="value-section"
							>
								<span class="value-label">Implant placement</span>

								<select
									v-model="edits[item.key].boobsPlacement"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option value="over">Over muscle</option>
									<option value="under">Under muscle</option>
								</select>
							</div>

							<div
								v-if="edits[item.key].naturalBoobs === false"
								class="value-section value-divide"
							>
								<span class="value-label">Surgeon</span>

								<input
									v-model="edits[item.key].boobsSurgeon"
									class="volume input"
									placeholder="Surgeon"
									list="surgeons"
									:disabled="!editing.has(item.key)"
								>

								<datalist id="surgeons">
									<option value="Dr. Revis" />
									<option value="Dr. Dre" />
								</datalist>
							</div>

							<div class="value-section">
								<span class="value-label">Natural butt</span>

								<select
									v-model="edits[item.key].naturalButt"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option :value="true">Yes</option>
									<option :value="false">No</option>
								</select>
							</div>

							<div
								v-if="edits[item.key].naturalButt === false"
								class="value-section"
							>
								<span class="value-label">Implant CC</span>

								<input
									v-model="edits[item.key].buttVolume"
									type="number"
									class="volume input"
									placeholder="CC"
									min="50"
									max="10000"
									:disabled="!editing.has(item.key)"
								>
							</div>

							<div
								v-if="edits[item.key].naturalButt === false"
								class="value-section"
							>
								<span class="value-label">Implant type</span>

								<select
									v-model="edits[item.key].buttImplant"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option value="bbl">BBL (fat transfer)</option>
									<option value="lift">Direct lift</option>
									<option value="filler">Filler (Sculptra)</option>
									<option value="mms">MMS (CoolTone)</option>
									<option value="lipo">Lipo without BBL</option>
								</select>
							</div>
						</div>

						<div
							v-if="item.type === 'penis'"
							class="figure penis"
						>
							<div class="value-section">
								<span class="value-label">Units</span>

								<select
									v-model="penisUnits"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option value="imperial">Imperial</option>
									<option value="metric">Metric</option>
								</select>
							</div>

							<div class="value-section">
								<span class="value-label">Penis length</span>

								<input
									v-model="edits[item.key].penisLength"
									type="number"
									class="volume input"
									min="1"
									max="20"
									:disabled="!editing.has(item.key)"
								>
							</div>

							<div class="value-section">
								<span class="value-label">Penis girth</span>

								<input
									v-model="edits[item.key].penisGirth"
									type="number"
									class="volume input"
									min="1"
									max="20"
									:disabled="!editing.has(item.key)"
								>
							</div>

							<div class="value-section">
								<span class="value-label">Circumcised</span>

								<select
									v-model="edits[item.key].isCircumcised"
									class="input"
									:disabled="!editing.has(item.key)"
								>
									<option :value="null" />
									<option :value="true">Yes</option>
									<option :value="false">No</option>
								</select>
							</div>
						</div>

						<div
							v-if="item.type === 'has'"
							class="has"
						>
							<select
								v-model="edits[item.key].has"
								class="select input"
								:disabled="!editing.has(item.key)"
							>
								<option :value="null" />
								<option :value="true">Yes</option>
								<option :value="false">No</option>
							</select>

							<input
								v-model="edits[item.key].description"
								class="description input"
								placeholder="Description"
								:disabled="!editing.has(item.key)"
							>
						</div>

						<div
							v-if="item.type === 'avatar'"
							class="avatars"
							:class="{ disabled: !editing.has(item.key) }"
						>
							<Avatar
								v-for="avatar in item.options"
								:key="`avatar-${avatar.id}`"
								:avatar="avatar"
								:class="{ selected: edits[item.key] === avatar.id }"
								@click="setAvatar(avatar.id)"
							/>
						</div>
					</div>
				</li>
			</ul>

			<div class="editor-footer">
				<div class="comment">
					<textarea
						v-model="comment"
						rows="3"
						placeholder="Please provide verifiable information and sources supporting your edits."
						class="text input noshrink"
					/>
				</div>

				<div class="editor-actions">
					<Checkbox
						v-if="user.role !== 'user'"
						label="Approve and apply immediately"
						:checked="apply"
						:disabled="editing.size === 0"
						@change="(checked) => apply = checked"
					/>

					<!-- we don't want the return key to submit the form -->
					<button
						class="button button-primary"
						type="button"
						:disabled="editing.size === 0"
						@click="submit"
					>
						<template v-if="apply">Submit</template>
						<template v-else>Submit for review</template>
					</button>
				</div>
			</div>
		</form>
	</div>
</template>

<script setup>
import { ref, computed, inject } from 'vue';
import { format } from 'date-fns';

import Avatar from '#/components/edit/avatar.vue';
import Checkbox from '#/components/form/checkbox.vue';

import {
	// get,
	post,
} from '#/src/api.js';

const pageContext = inject('pageContext');

const user = pageContext.user;
const countries = pageContext.pageProps.countries;
const actor = ref(pageContext.pageProps.actor);

const topCountries = [
	'AU',
	'BR',
	'CZ',
	'DE',
	'JP',
	'RU',
	'GB',
	'US',
];

const sortedCountries = countries.toSorted((countryA, countryB) => topCountries.indexOf(countryB.alpha2) - topCountries.indexOf(countryA.alpha2));

/*
const cupSizes = [
	'A', 'AA',
	'B',
	'C',
	'D', 'DD', 'DDD',
	'E',
	'F', 'FF',
	'G', 'GG',
	'H', 'HH',
	'J', 'JJ',
	'K', 'KK',
	'L',
	'M',
	'N',
	'O',
	'P',
];
*/

const cupSizes = {
	us: ['AA', 'A', 'B', 'C', 'D', ['DD', 'E'], ['DDD', 'F'], 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'], // United States
	uk: ['AA', 'A', 'B', 'C', 'D', 'DD', 'E', 'F', 'FF', 'G', 'GG', 'H', 'HH', 'J', 'JJ', 'K', 'KK'], // United Kingdom
	eu: ['AA', 'A', 'B', 'C', 'D', 'E', 'F', 'G', ' H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'], // Europe
	jp: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q'], // Japan
};

cupSizes.fr = cupSizes.eu; // France
cupSizes.it = cupSizes.uk; // Italy
cupSizes.au = cupSizes.uk; // Australia

// bra band sizes
const bustSizes = {
	us: [28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56],
	eu: [60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130],
	fr: [75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145],
	it: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
	au: [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34],
};

bustSizes.uk = bustSizes.us;
bustSizes.jp = bustSizes.eu;

const avatars = Object.values(Object.fromEntries(actor.value.profiles.filter((profile) => !!profile.avatar).map((profile) => [profile.avatar.id, profile.avatar])));

const fields = computed(() => [
	...(avatars.length > 0 ? [{
		key: 'avatar',
		type: 'avatar',
		value: actor.value.avatar?.id,
		options: avatars,
	}] : []),
	...(user.role === 'admin'
		? [{
			key: 'name',
			type: 'string',
			value: actor.value.name,
		}]
		: []),
	{
		key: 'gender',
		type: 'select',
		value: actor.value.gender,
		options: ['female', 'male', 'transsexual', 'other', null],
		inline: true,
	},
	{
		key: 'dateOfBirth',
		label: 'date of birth',
		type: 'date',
		value: actor.value.dateOfBirth
			? format(actor.value.dateOfBirth, 'yyyy-MM-dd')
			: null,
		inline: true,
	},
	{
		key: 'origin',
		type: 'place',
		value: {
			...actor.value.origin,
			country: actor.value.origin?.country?.alpha2 || null,
		},
	},
	{
		key: 'residence',
		type: 'place',
		value: {
			...actor.value.residence,
			country: actor.value.residence?.country?.alpha2 || null,
		},
	},
	{
		key: 'height',
		type: 'number',
		value: actor.value.height?.metric,
		unit: 'cm',
		inline: true,
	},
	{
		key: 'weight',
		type: 'number',
		value: actor.value.weight?.metric,
		unit: 'kg',
		inline: true,
	},
	{
		key: 'figure',
		type: 'figure',
		value: {
			bust: actor.value.bust,
			cup: actor.value.cup,
			waist: actor.value.waist,
			hip: actor.value.hip,
		},
	},
	{
		key: 'augmentation',
		type: 'augmentation',
		value: {
			naturalBoobs: actor.value.naturalBoobs,
			boobsVolume: actor.value.boobsVolume,
			boobsImplant: actor.value.boobsImplant,
			boobsPlacement: actor.value.boobsPlacement,
			boobsSurgeon: actor.value.boobsSurgeon,
			naturalButt: actor.value.naturalButt,
			buttVolume: actor.value.buttVolume,
			buttImplant: actor.value.buttImplant,
		},
	},
	{
		key: 'hairColor',
		label: 'hair color',
		type: 'select',
		value: actor.value.hairColor,
		options: [
			null,
			'black',
			'blonde',
			'brown',
			'red',
			'gray',
			'blue',
			'green',
			'pink',
			'purple',
		],
		inline: true,
	},
	{
		key: 'eyes',
		label: 'eye color',
		type: 'select',
		value: actor.value.eyes,
		options: [
			null,
			'blue',
			'brown',
			'gray',
			'green',
			'hazel',
		],
		inline: true,
	},
	{
		key: 'tattoos',
		type: 'has',
		value: {
			has: actor.value.hasTattoos,
			description: actor.value.tattoos,
		},
	},
	{
		key: 'piercings',
		type: 'has',
		value: {
			has: actor.value.hasPiercings,
			description: actor.value.piercings,
		},
	},
	{
		key: 'agency',
		type: 'string',
		value: actor.value.agency,
		suggestions: [
			'101 Modeling',
			'Adult Talent Managers (ATMLA)',
			'The Bakery Talent',
			'Coxxx Models',
			'East Coast Talent (ECT)',
			'Hussie Models',
			'Invision Models',
			'OC Modeling',
			'Spiegler Girls',
		],
	},
	{
		key: 'penis',
		type: 'penis',
		value: {
			penisLength: actor.value.penisLength,
			penisGirth: actor.value.penisGirth,
			isCircumcised: actor.value.isCircumcised,
		},
	},
	{
		key: 'dateOfDeath',
		label: 'date of death',
		type: 'date',
		value: actor.value.dateOfDeath
			? format(actor.value.dateOfDeath, 'yyyy-MM-dd')
			: null,
	},
]);

const editing = ref(new Set());
const edits = ref(Object.fromEntries(fields.value.map((field) => [field.key, field.value])));
const comment = ref(null);
const apply = ref(user.role !== 'user');
const submitted = ref(false);

const figureUnits = ref('us');
const penisUnits = ref('imperial');

function toggleField(item) {
	if (editing.value.has(item.key)) {
		editing.value.delete(item.key);
		// delete edits.value[item.key];

		return;
	}

	editing.value.add(item.key);
}

function setAvatar(avatarId) {
	edits.value.avatar = avatarId;
}

const keyMap = {
	origin: {
		country: 'originCountry',
		state: 'originState',
		city: 'originCity',
	},
	residence: {
		country: 'residenceCountry',
		state: 'residenceState',
		city: 'residenceCity',
	},
};

async function submit() {
	try {
		await post('/revisions/actors', {
			actorId: actor.value.id,
			edits: Object.fromEntries(Array.from(editing.value).flatMap((key) => {
				if (edits.value[key] && typeof edits.value[key] === 'object') {
					return Object.entries(edits.value[key]).map(([valueKey, value]) => [keyMap[key]?.[valueKey] || valueKey, value]);
				}

				return [[key, edits.value[key]]];
			})),
			figureUnits: figureUnits.value,
			penisUnits: penisUnits.value,
			comment: comment.value,
			apply: apply.value,
		}, {
			successFeedback: 'Your revision has been submitted for approval.',
			appendErrorMessage: true,
		});

		editing.value = new Set();
		edits.value = {};
		comment.value = null;

		submitted.value = true;

		// actor.value = await get(`/actors/${actor.value.id}`);
	} catch (error) {
		console.error(error);
	}
}
</script>

<style scoped>
.editor {
	flex-grow: 1;
	background: var(--background-dark-10);
}

.editor-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 1rem;
}

.heading {
	margin: 0;
}

.row {
	display: flex;
	align-items: center;
	padding: .25rem 1rem;
	margin-bottom: .25rem;

	&.inline {
		display: inline-flex;

		& + .inline .key {
			width: auto;
		}
	}
}

.key {
	width: 10rem;
	text-transform: capitalize;
	font-weight: bold;
}

.input {
	background: var(--background);
}

.row .input {
	height: 2.5rem;
	flex-shrink: 0;
	min-width: 7rem;
}

.select {
	text-transform: capitalize;
}

.item-header {
	display: flex;
	align-items: center;
}

.value {
	display: flex;
	align-items: center;
	flex-grow: 1;

	.input {
		flex-grow: 1;

		&:disabled {
			color: var(--glass-strong-10);
			background: none;
			border: solid 1px var(--glass-weak-30);
		}
	}

	.duration {
		.input {
			width: 5rem;
			margin-right: .25rem;

			&:not(:first-child) {
				margin-left: .75rem;
			}
		}
	}

	.number.input {
		width: 6rem;
		flex-grow: 0;
		margin-right: .5rem;
	}

	&.disabled {
		pointer-events: none;
	}
}

.value-section {
	max-width: 100%;
	display: flex;
	flex-direction: column;
}

.value-label {
	padding: 0 .25rem;
	margin-bottom: .25rem;
	color: var(--shadow-strong-10);
	font-size: .8rem;
	font-weight: bold;
}

.value-divide {
	padding-right: 1rem;
	border-right: solid 1px var(--shadow-weak-30);
	margin-right: .5rem;
}

.place,
.has,
.figure {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: .5rem;
	overflow: hidden;
}

.figure {
	.input[type="number"] {
		width: 5rem;
	}

	.input[type="number"].volume {
		width: 6rem;
	}
}

.figure-bust {
	display: flex;
	align-items: center;
}

.has {
	flex-grow: 1;

	.select {
		flex-grow: 0;
	}

	.description {
		flex-grow: 1;
	}
}

.avatars {
	display: flex;
	gap: .25rem;
	padding-bottom: .5rem;
	overflow-x: auto;

	&.disabled {
		opacity: .5;
	}
}

.item-actions {
	.icon {
		padding: .25rem 1rem;
		fill:  var(--glass);
		overflow: hidden;

		&:hover {
			cursor: pointer;
			fill: var(--text);
		}

		&.active {
			fill: var(--primary);
		}
	}
}

.editor-footer {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1rem;
	padding: 1rem 1rem 0 1rem;
	border-top: solid 1px var(--primary-light-30);
	margin: 1rem 0;
}

.comment {
	width: 100%;
	flex-shrink: 0;

	.input {
		width: 100%;
		resize: vertical;
	}
}

.editor-actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.5rem;
	margin: .5rem 0;

	.button {
		padding: .5rem 1rem;
		font-size: 1.1rem;
	}
}

.submitted {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 1rem;
	font-weight: bold;
	line-height: 1.5;
}

@media(--small) {
	.row {
		flex-direction: column;
		align-items: stretch;
		margin-bottom: .25rem;
	}

	.item-header {
		margin-bottom: .25rem;
	}

	.key {
		flex-grow: 1;
	}
}
</style>
