import {
	Button,
	Col,
	Descriptions,
	Divider,
	Form,
	InputNumber,
	Modal,
	Row,
	Select,
	Space,
	Toast
} from "@douyinfe/semi-ui";
import {IconAlertCircle} from "@douyinfe/semi-icons";
import {Data} from "@douyinfe/semi-ui/lib/es/descriptions";
import React, {useMemo} from "react";
import {useTranslation} from "react-i18next";
import {useSetState} from "ahooks";

import {useBillTypes} from "@/hooks/useBillTypes.ts";
import {usePaymentChannels} from "@/hooks/usePaymentChannels.ts";
import {addBillRecord} from "@/service/api/bill.ts"
import dayjs from "dayjs";
import MoneyFormat from "@/components/money-format.tsx";
import {BizError} from "@/service/types.ts";

type BillPaidModalProps = {
	onConfirm: () => void
	onCancel?: () => void
}
type BillTypeListProps = {
	onClose?: (refresh?: boolean) => void;
	onChange?: (confirms: ConfirmedBillDetail[]) => void;
}

export const BillTypeList: React.FC<BillTypeListProps> = (props) => {
	const {t} = useTranslation()
	const [state, setState] = useSetState<{
		confirmed: ConfirmedBillDetail[]
	}>({
		confirmed: [{bill_type: '', amount: 0}]
	})
	const BillTypes = useBillTypes()

	const onChange = (value: string, index: number, type: 'type' | 'amount') => {
		if (state.confirmed.length <= index || !value) return;
		const confirmed = [...state.confirmed]
		if (type == 'type') {
			confirmed[index].bill_type = value
		} else {
			confirmed[index].amount = Number(value)
		}

		setState({confirmed})
		props.onChange?.(confirmed)
	}

	const addOrRemove = (index: number) => {
		// 不允许删除最后一个
		if (index > -1 && state.confirmed.length <= 1) return;
		const confirmed = [...state.confirmed, ...(index == -1 ? [{bill_type: '', amount: 0}] : [])]
		if (index > -1) confirmed.splice(index, 1)
		setState({confirmed})
		props.onChange?.(confirmed)
	}


	return (<div className={'bill-type-list'} style={{marginTop: 10}}>
		<Divider>{t('bill.title_bill_detail')}</Divider>
		{
			state.confirmed.map((item, index) => (
				<div key={index} className="confirm-item-btn align-center space-between" style={{marginTop: 20}}>
					<Select
						value={item.bill_type}
						style={{width: 240}}
						onChange={v => onChange(String(v), index, 'type')}
						placeholder={t('base.please_select_bill_type')}>
						{
							BillTypes.map((it, idx) => (
								<Select.Option key={idx} value={it.label}>{it.label}</Select.Option>))
						}
					</Select>

					<Space spacing={10}>
						<InputNumber
							hideButtons precision={2} value={item.amount} type={'number'}
							onChange={v => onChange(String(v), index, 'amount')} style={{width: 140}}/>
						<Button
							disabled={state.confirmed.length <= 1} onClick={() => addOrRemove(index)}
							theme={'solid'} type={'secondary'}>{t('base.remove')}</Button>
					</Space>
				</div>
			))
		}
		<div style={{marginTop: 10, marginBottom: 20}}>
			<Button onClick={() => addOrRemove(-1)}>{t('base.add')}</Button>
		</div>
	</div>)
}

export const AddBillModal: React.FC<BillPaidModalProps> = (props) => {
	const {t, i18n} = useTranslation()
	const {paymentChannelList, paymentMethodList} = usePaymentChannels();

	const [state, setState] = useSetState<{
		loading?: boolean;
		confirmLoading?: boolean;
		open?: boolean;
		details: ConfirmedBillDetail[];
		errorMessage?: string;
		errorConfirmMessage?: string;
		errorConfirmOk?: boolean;
		values?: CreateBillRecordModel;
	}>({
		details: []
	})


	const onSubmit = (values: CreateBillRecordModel) => {
		if (state.details.length == 0) {
			setState({errorMessage: t('base.validate.error_details_message')})
			return;
		}
		for (const it of state.details) {
			if (!it.bill_type || it.amount <= 0) {
				setState({errorMessage: t('base.validate.error_details_message')})
				return;
			}
		}
		values.details = state.details
		values.check_student = true;
		values.initiated_paid_date = dayjs(values.initiated_paid_date).format("YYYY-MM-DD")
		values.paid_date = dayjs(values.paid_date).format("YYYY-MM-DD")
		values.delivered_date = dayjs(values.delivered_date).format("YYYY-MM-DD")
		setState({
			loading: true, errorMessage: undefined,
			values,errorConfirmOk:false
		})
		addBillRecord(values).then(() => {
			setState({open: false})
			Toast.success(t('base.add_success'))
			props.onConfirm()
		}).catch((e: BizError) => {
			if (e.code == -50415) { // STUDENT_INFO_NOT_FOUND
				// duplicate
				setState({errorConfirmMessage: e.message,errorConfirmOk:true})
			} else {
				setState({errorConfirmMessage: e.message})
			}
		}).finally(() => {
			setState({
				loading: false
			})
		})
		//
	}
	const handleClose = () => {
		setState({
			loading: false,
			open: false,
			errorMessage: undefined
		})
	}

	// process confirm
	const handleCloseConfirm = () => {
		setState({errorConfirmMessage: undefined})
	}
	const handleConfirmAdd = () => {
		if (!state.values) return;
		setState({confirmLoading: true})
		state.values.check_student = false;
		addBillRecord(state.values).then(() => {
			setState({
				loading: false,
				open: false,
				errorMessage: undefined,
				errorConfirmMessage: undefined,
			})
			Toast.success(t('base.add_success'))
			props.onConfirm()
		}).catch(e => {
			setState({errorConfirmMessage: e.message})
		}).finally(() => {
			setState({
				confirmLoading: false,
			})
		})
	}

	const details = useMemo(() => {
		if (!state.values) return;
		const {
			application_number, payment_channel, payment_method,
			student_email, merchant_ref, paid_area,
			initiated_paid_date, paid_date, delivered_date
		} = state.values
		//, span: 2
		const _data: Data[] = [
			{key: 'Merchant Ref', value: merchant_ref},
			{key: t('bill.bill_number'), value: application_number},
			{key: 'Email', value: student_email},
			{key: t('bill.title_pay_channel'), value: payment_channel},
			{key: t('bill.title_pay_method'), value: payment_method},
			{key: t('bill.create.pay_area'), value: paid_area},
			{key: t('bill.title_initiated_paid_at'), value: initiated_paid_date},
			{key: t('bill.title_paid_at'), value: paid_date},
			{key: t('bill.title_delivered_at'), value: delivered_date, span: 2},
		]
		state.details.forEach(it => {
			_data.push({key: t('bill.title_bill_type'), value: it.bill_type})
			_data.push({key: t('bill.title_amount'), value: <MoneyFormat money={it.amount}/>})
		});
		return _data
	}, [i18n.language, state.values]);
	return (<>
		<Button onClick={() => setState({open: true})} theme={'solid'}>{t('bill.add_bill_record')}</Button>
		<Modal
			title={t('bill.add_bill_record')}
			visible={state.open}
			closeOnEsc={true}
			onCancel={handleClose}
			footer={null}
			width={600}
			maskClosable={false}
		>
			<Form<CreateBillRecordModel> onSubmit={onSubmit} initValues={{
				merchant_ref: '',
				application_number: '',
				student_email: '',
				paid_area: '',
				initiated_paid_date: '',
				paid_date: '',
				delivered_date: '',
				payment_method: '',
				payment_channel: '',
				check_student: true,
				details: []
			}}>
				<Row gutter={20}>
					<Col span={12}>
						<Form.Input
							rules={[
								{required: true, message: 'required error'},
							]}
							showClear field="merchant_ref" label="Merchant Ref"
							placeholder={t('base.please_enter')} style={{width: '100%'}}/>
					</Col>
					<Col span={12}>
						<Form.Input
							rules={[
								{required: true, message: 'required error'},
							]}
							showClear field="application_number" label={t('bill.bill_number')}
							placeholder={t('base.please_enter')} style={{width: '100%'}}/>
					</Col>
				</Row>
				<Row gutter={20}>
					<Col span={12}>
						<Form.Input
							rules={[
								{required: true, message: 'required error'},
								{type: 'email', message: t('base.validate.email')}
							]}
							type={'email'}
							showClear field="student_email" label="Email"
							placeholder={t('base.please_enter')} style={{width: '100%'}}/>
					</Col>
					<Col span={12}>
						<Form.Input
							rules={[
								{required: true, message: 'required error'},
							]}
							showClear field="paid_area" label={t('bill.create.pay_area')}
							placeholder={t('base.please_enter')} style={{width: '100%'}}/>
					</Col>
				</Row>
				<Row gutter={20}>
					<Col span={12}>
						<Form.Select
							rules={[
								{required: true, message: 'required error'},
							]}
							optionList={paymentChannelList}
							allowCreate filter showClear field="payment_channel" label={t('bill.title_pay_channel')}
							placeholder={t('base.please_select')} style={{width: '100%'}}/>
					</Col>
					<Col span={12}>
						<Form.Select
							rules={[
								{required: true, message: 'required error'},
							]}
							optionList={paymentMethodList}
							allowCreate filter showClear field="payment_method" label={t('bill.title_pay_method')}
							placeholder={t('base.please_select')} style={{width: '100%'}}/>
					</Col>
				</Row>
				<Row gutter={20}>
					<Col span={12}>
						<Form.DatePicker
							showClear
							rules={[
								{required: true, message: 'required error'},
							]}
							type={'date'}
							field="initiated_paid_date"
							label={t('bill.title_initiated_paid_at')}
							style={{width: '100%'}}
						/>
					</Col>
					<Col span={12}>
						<Form.DatePicker
							showClear
							rules={[
								{required: true, message: 'required error'},
							]}
							type={'date'}
							field="paid_date"
							label={t('bill.title_paid_at')}
							style={{width: '100%'}}
						/>
					</Col>
				</Row>
				<Row gutter={20}>
					<Col span={12}>
						<Form.DatePicker
							showClear
							rules={[
								{required: true, message: 'required error'},
							]}
							type={'date'}
							field="delivered_date"
							label={t('bill.title_delivered_at')}
							style={{width: '100%'}}
						/>
					</Col>
				</Row>
				<div>
					<BillTypeList onChange={(details) => setState({details})}/>
					{state.errorMessage &&
                        <div className="semi-form-field-error-message align-center" style={{marginBottom: 10}}>
                            <IconAlertCircle/>
                            <span style={{marginLeft: 5}}>{state.errorMessage}</span>
                        </div>}
					<Divider/>
				</div>
				<div className={'text-right'} style={{margin: '20px 0'}}>
					<Space spacing={12}>
						<Button onClick={handleClose} type={'tertiary'}>{t('base.cancel')}</Button>
						<Button
							loading={state.loading} htmlType={'submit'} theme={'solid'}
							type={'primary'}>{t('bill.create.confirm')}</Button>
					</Space>
				</div>
			</Form>
		</Modal>

		<Modal
			visible={!!state.errorConfirmMessage}
			title={t('base.confirm_information')}
			closeOnEsc={true}
			onCancel={handleCloseConfirm}
			width={600}
			maskClosable={false}
			footer={
			<div className={'text-center'}>
                <Space>
	                <Button onClick={handleCloseConfirm} type={'tertiary'}>{t('base.cancel')}</Button>
	                {state.errorConfirmOk && <Button loading={state.confirmLoading} onClick={handleConfirmAdd} theme={'solid'}>
		                {t('base.confirm_and_add')}
                    </Button>}
                </Space>
			</div>
			}
		>
			<Descriptions layout='horizontal' align='plain' data={details} column={2}/>
			<Divider style={{margin: '10px 0'}}>{t('base.title_error_tip')}</Divider>
			{state.errorConfirmMessage &&
                <div className="semi-form-field-error-message align-center" style={{marginBottom: 10}}>
                    <IconAlertCircle/>
                    <span style={{marginLeft: 5}}>{state.errorConfirmMessage}</span>
                </div>}
		</Modal>
	</>)
}