import React, { Fragment, useState, useEffect, useLayoutEffect, useContext } from 'react';
import { ActivityIndicator, Text, View } from 'react-native';
import session from '~/Utils/session';
import fetchGet, { fetchPut, fetchPost, fetchDelete } from '~/Utils/fetch';
import { useToast, confirm } from '~/Components/UIControls/Message';
import Form from '~/Components/Form';
import Button from '~/Components/UIControls/Button';
import { useForm } from 'react-hook-form';
import { useAuth } from '~/Components/Hooks';
import BottomTabBarLayout from '~/Components/Layouts/BottomTabBarLayout';
import { UploadFileType } from '~/Components/UIControls/UploadFile';
import { usePopup } from '~/Components/UIControls/Popup';
import { Util } from '~/Utils/utils';

const Screen = ({ navigation }) => {
    const action = navigation.getParam('action', Form.VIEW);
    const editable = navigation.getParam('editable', action == Form.VIEW ? false : true);
    const setEditable = (value) => {
        navigation.setParams({ editable: value });
    };
    const refreshList = navigation.getParam('refreshList', () => {});
    const siteId = navigation.getParam('siteId', '');
    const materialId = navigation.getParam('materialId', 0);

    const [ready, setReady] = useState(false);
    const [loading, setLoading] = useState(false);
    const [data, setData] = useState({
        FmsMaterialCodeClass: {},
        FmsMaterialCodeClass1: {},
        FmsMaterialCodeClass2: {},
        IsUse: true,
        IsDiscontinued: false,
    });
    const [materialCode, setMaterialCode] = useState({ name1: '', name2: '', name3: '' });
    const { showMessage } = useToast();
    const { auth, config } = useAuth(navigation);

    // mount
    useEffect(() => {
        fetch();
    }, [editable]);

    // unmount
    useEffect(() => () => {}, []);

    // popup
    const { openPopup } = usePopup();

    // react hook form initialize
    const { register, setValue, handleSubmit, errors, getValues } = useForm();
    useLayoutEffect(() => {
        Form.setUseFormFunctions(register, setValue);
    }, [register]);

    // search
    const fetch = async () => {
        setLoading(true);
        await session.load();

        if (action != Form.CREATE) {
            try {
                console.log('get - ', `api/Material/${siteId}/${materialId}`);
                const result = await fetchGet(`api/Material/${siteId}/${materialId}`);
                console.log(result);
                setData(result);
                Form.setFormData(result);
                setMaterialCode({
                    name1: Util.get(data, 'FmsMaterialCodeClass.Name', ''),
                    name2: Util.get(data, 'FmsMaterialCodeClass1.Name', ''),
                    name3: Util.get(data, 'FmsMaterialCodeClass2.Name', ''),
                });
            } catch (error) {
                showMessage(error.message);
            }
        }

        setLoading(false);
    };

    // edit
    const onEdit = async () => {
        await fetch();
        setEditable(true);
    };

    // cancel edit
    const onCancelEdit = async () => {
        await fetch();
        setEditable(false);
    };

    // save
    const onSave = async (form) => {
        if (loading) {
            showMessage('저장중입니다. 잠시만기다려 주세요.');
            return;
        }
        confirm('저장', '저장하시겠습니까?', async () => {
            setLoading(true);
            const submit = {
                ...form,
                SiteId: siteId,
                CmFile: !form.CmFile.IsUpload && !form.CmFile.IsDelete ? null : form.CmFile,
                MaterialId: data.MaterialId,
                MaterialCode: Object.values(materialCode)
                    .filter((x) => x)
                    .join('-'),
            };
            console.log('submit data', submit);

            try {
                if (action == Form.CREATE) {
                    const result = await fetchPut('api/Material', submit);
                    showMessage('저장되었습니다.');
                    refreshList();
                    navigation.pop();
                } else {
                    const result = await fetchPost(`api/Material/${siteId}/${materialId}`, submit);
                    showMessage('저장되었습니다.');
                    refreshList();
                    setEditable(false);
                }
            } catch (error) {
                showMessage(error.message);
            }
            setLoading(false);
        });
    };

    // delete
    const onDelete = async () => {
        if (loading) {
            showMessage('처리중입니다. 잠시만기다려 주세요.');
            return;
        }
        confirm('삭제', '삭제하시겠습니까?', async () => {
            setLoading(true);
            try {
                await fetchDelete(`api/Material/${siteId}/${materialId}`);

                showMessage('삭제되었습니다.');
                refreshList();
                navigation.pop();
            } catch (error) {
                showMessage(error.message);
            }
            setLoading(false);
        });
    };

    return (
        <BottomTabBarLayout>
            {
                <Form.Container
                    onSave={handleSubmit(onSave)}
                    onDelete={onDelete}
                    onEdit={onEdit}
                    onCancelEdit={onCancelEdit}
                    loading={loading}
                >
                    {/* FileId // upload image */}
                    <Form.Field>
                        <Form.TitleTop>
                            <Form.Label>이미지</Form.Label>
                        </Form.TitleTop>
                        <Form.UploadFile
                            type={UploadFileType.Image}
                            editable={editable}
                            defaultFile={data.CmFile}
                            onUpload={(isUpload, result) => {
                                setValue('CmFile.IsUpload', isUpload, false);
                                setValue('CmFile.Name', result.Name, false);
                                setValue('CmFile.Url', result.Url, false);
                                setValue('CmFile.Path', result.Path, false);
                                setValue('CmFile.FileSize', result.FileSize, false);
                                setValue('CmFile.ContentType', result.ContentType, false);
                            }}
                            onDelete={() => {
                                setValue('CmFile.IsDelete', true, false);
                            }}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="CmFile.IsUpload" value={false} />
                    <Form.Regist editable={editable} name="CmFile.IsDelete" value={false} />
                    <Form.Regist editable={editable} name="CmFile.Name" value={data.CmFile ? data.CmFile.Name : ''} />
                    <Form.Regist editable={editable} name="CmFile.Url" value={data.CmFile ? data.CmFile.Url : ''} />
                    <Form.Regist editable={editable} name="CmFile.Path" value={data.CmFile ? data.CmFile.Path : ''} />
                    <Form.Regist editable={editable} name="CmFile.FileSize" value="" />
                    <Form.Regist editable={editable} name="CmFile.ContentType" value="" />

                    {/* Name // input */}
                    <Form.Field>
                        <Form.Require>
                            <Form.Label>자재명</Form.Label>
                        </Form.Require>
                        <Form.Input
                            placeholder="자재명"
                            defaultValue={data.Name}
                            onChangeText={(text) => setValue('Name', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="Name" rule={{ required: '자재명을 입력하세요.' }} error={errors.Name} />

                    {/* FacilityTypeId // entityselect */}
                    <Form.Field>
                        <Form.Require>
                            <Form.Label>업무분야</Form.Label>
                        </Form.Require>
                        <Form.EntitySelect
                            entity="CmBusinessField"
                            defaultLabel="업무분야"
                            selectedValue={data.BusinessFieldId}
                            selectedText={Util.get(data, 'CmBusinessField.Name')}
                            editable={editable}
                            useCheck={true}
                            auth={auth}
                            onChange={(item) => {
                                setValue('BusinessFieldId', item.value, true);
                            }}
                        />
                    </Form.Field>
                    <Form.Regist
                        editable={editable}
                        name="BusinessFieldId"
                        rule={{ required: '업무분야를 선택하세요.' }}
                        error={errors.BusinessFieldId}
                    />

                    {/* MaterialTypeId // entityselect */}
                    {config.UseMaterialType && (
                        <>
                            <Form.Field>
                                <Form.Require>
                                    <Form.Label>자재구분</Form.Label>
                                </Form.Require>
                                <Form.EntitySelect
                                    entity="FmsMaterialCodeType"
                                    defaultLabel="자재구분"
                                    id="MaterialTypeId"
                                    useCheck={true}
                                    selectedValue={data.MaterialTypeId}
                                    selectedText={Util.get(data, 'FmsMaterialCodeType.Name')}
                                    editable={editable}
                                    onChange={(item) => {
                                        setValue('MaterialTypeId', item.value, true);
                                    }}
                                />
                            </Form.Field>
                            <Form.Regist
                                editable={editable}
                                name="MaterialTypeId"
                                rule={{ required: '자재구분을 선택하세요.' }}
                                error={errors.MaterialTypeId}
                            />
                        </>
                    )}

                    {/* Standard // input */}
                    <Form.Field>
                        <Form.Title>
                            <Form.Label>규격</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="규격"
                            defaultValue={data.Standard}
                            onChangeText={(text) => setValue('Standard', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="Standard" />

                    {/* Unit // input */}
                    <Form.Field>
                        <Form.Title>
                            <Form.Label>단위</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="단위"
                            defaultValue={data.Unit}
                            onChangeText={(text) => setValue('Unit', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="Unit" />

                    {/* DurableYears // input */}
                    <Form.Field>
                        <Form.Title>
                            <Form.Label>내용연수</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="내용연수"
                            defaultValue={data.DurableYears}
                            onChangeText={(text) => setValue('DurableYears', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="DurableYears" />

                    {/* Category // switch */}
                    <Form.Field>
                        <Form.Require>
                            <Form.Label>자재분류</Form.Label>
                        </Form.Require>
                        {action == Form.VIEW && !editable ? (
                            <Text>
                                {[data.FmsMaterialCodeClass.Name, data.FmsMaterialCodeClass1.Name, data.FmsMaterialCodeClass2.Name]
                                    .filter((x) => x)
                                    .join(' > ')}
                            </Text>
                        ) : (
                            <>
                                <Form.Group>
                                    <Form.EntitySelect
                                        entity="FmsMaterialCodeClass"
                                        id="MaterialClassId"
                                        where={'ParentMaterialClassId IS NULL'}
                                        defaultLabel="자재분류-대"
                                        selectedValue={data.FirstClassId}
                                        selectedText={Util.get(data, 'FmsMaterialCodeClass.Name')}
                                        editable={editable}
                                        useCheck={true}
                                        onChange={(item) => {
                                            console.log('item', item);
                                            setData({ ...data, FirstClassId: item.value, SecondClassId: '', ThirdClassId: '' });
                                            setValue('FirstClassId', item.value, true);
                                            setValue('SecondClassId', '', true);
                                            setValue('ThirdClassId', '', true);
                                            setMaterialCode({
                                                name1: item.label,
                                                name2: '',
                                                name3: '',
                                            });
                                        }}
                                    />
                                    <Form.Regist
                                        editable={editable}
                                        name="FirstClassId"
                                        rule={{ required: '자재분류-대를 선택하세요.' }}
                                        error={errors.FirstClassId}
                                    />
                                    <Form.EntitySelect
                                        entity="FmsMaterialCodeClass"
                                        id="MaterialClassId"
                                        where={`ParentMaterialClassId = '${data.FirstClassId}'`}
                                        defaultLabel="자재분류-중"
                                        selectedValue={data.SecondClassId}
                                        selectedText={Util.get(data, 'FmsMaterialCodeClass1.Name')}
                                        editable={editable}
                                        useCheck={true}
                                        onChange={(item) => {
                                            setData({ ...data, SecondClassId: item.value, ThirdClassId: '' });
                                            setValue('SecondClassId', item.value, true);
                                            setValue('ThirdClassId', '', true);
                                            setMaterialCode({
                                                ...materialCode,
                                                name2: item.label,
                                                name3: '',
                                            });
                                        }}
                                    />
                                    <Form.Regist editable={editable} name="SecondClassId" error={errors.SecondClassId} />
                                    <Form.EntitySelect
                                        entity="FmsMaterialCodeClass"
                                        id="MaterialClassId"
                                        where={`ParentMaterialClassId = '${data.SecondClassId}'`}
                                        defaultLabel="자재분류-소"
                                        selectedValue={data.ThirdClassId}
                                        selectedText={Util.get(data, 'FmsMaterialCodeClass2.Name')}
                                        editable={editable}
                                        useCheck={true}
                                        onChange={(item) => {
                                            setData({ ...data, ThirdClassId: item.value });
                                            setValue('ThirdClassId', item.value, true);
                                            setMaterialCode({
                                                ...materialCode,
                                                name3: item.label,
                                            });
                                        }}
                                    />
                                    <Form.Regist editable={editable} name="ThirdClassId" error={errors.ThirdClassId} />
                                </Form.Group>
                            </>
                        )}
                    </Form.Field>

                    {/* QR코드 // input */}
                    <Form.Field style={{display:'none'}}>
                        <Form.Title>
                            <Form.Label>QR코드</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="QR코드"
                            defaultValue={data.Rfid}
                            onChangeText={(text) => setValue('Rfid', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="Rfid" />

                    {/* Manufacturer // input */}
                    <Form.Field>
                        <Form.Title>
                            <Form.Label>제조사</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="제조사"
                            defaultValue={data.Manufacturer}
                            onChangeText={(text) => setValue('Manufacturer', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="Manufacturer" />

                    {/* FinalPrice // input */}
                    <Form.Field>
                        <Form.Title>
                            <Form.Label>단가</Form.Label>
                        </Form.Title>
                        <Form.Input
                            placeholder="단가"
                            defaultValue={data.FinalPrice}
                            onChangeText={(text) => setValue('FinalPrice', text, true)}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="FinalPrice" />

                    {/* ReasonableStockCount // input */}
                    {config.UseMaterialReasonableStockCount && (
                        <>
                            <Form.Field>
                                <Form.Title>
                                    <Form.Label>적정재고량</Form.Label>
                                </Form.Title>
                                <Form.Input
                                    placeholder="적정재고량"
                                    defaultValue={data.ReasonableStockCount}
                                    onChangeText={(text) => setValue('ReasonableStockCount', text, true)}
                                    editable={editable}
                                />
                            </Form.Field>
                            <Form.Regist editable={editable} name="ReasonableStockCount" />
                        </>
                    )}

                    {/* IsDiscontinued // switch */}
                    <Form.Field style={{display:'none'}}>
                        <Form.Title>
                            <Form.Label>단종여부</Form.Label>
                        </Form.Title>
                        <Form.Switch
                            initialValue={data.IsDiscontinued}
                            onValueChange={(newValue) => {
                                setValue('IsDiscontinued', newValue);
                            }}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="IsDiscontinued" value={data.IsDiscontinued} />

                    {/* IsUse // switch */}
                    <Form.Field style={{display:'none'}}>
                        <Form.Title>
                            <Form.Label>사용여부</Form.Label>
                        </Form.Title>
                        <Form.Switch
                            initialValue={data.IsUse}
                            onValueChange={(newValue) => {
                                setValue('IsUse', newValue);
                            }}
                            editable={editable}
                        />
                    </Form.Field>
                    <Form.Regist editable={editable} name="IsUse" value={data.IsUse} />

                    <Form.Field style={{ height: 30 }}></Form.Field>
                </Form.Container>
            }
        </BottomTabBarLayout>
    );
};

Screen.navigationOptions = ({ navigation }) => {
    const action = navigation.getParam('action', Form.VIEW); // create, edit, view
    const editable = navigation.getParam('editable', action == Form.VIEW ? false : true);
    const { auth } = useAuth(navigation);

    return {
        header: () => (
            <Header
                navigation={navigation}
                title={`자재정보`}
                main={false}
                buttons={
                    <Fragment>
                        {!editable && (
                            <Fragment>
                                {auth.Update && <Form.EditButton navigation={navigation} type="primary" />}
                                {auth.Delete && <Form.DeleteButton />}
                            </Fragment>
                        )}
                        {editable && (
                            <Fragment>
                                {auth.Update && <Form.SaveButton type="primary" />}
                                {action != Form.CREATE && auth.Update && <Form.CancelEditButton navigation={navigation} />}
                            </Fragment>
                        )}
                    </Fragment>
                }
            />
        ),
    };
};

export default Screen;
