import React, { Fragment, useState, useEffect, useLayoutEffect, useContext } from 'react';
import session from '~/Utils/session';
import fetchGet, { fetchPost, fetchDelete } from '~/Utils/fetch';
import { useToast, confirm, usePrompt } from '~/Components/UIControls/Message';
import Form from '~/Components/Form';
import { useForm } from 'react-hook-form';
import BottomTabBarLayout from '~/Components/Layouts/BottomTabBarLayout';
import { Tab, TabItem, TabTitleGroup, TabHeader, TabContent, TabTitle } from '~/Components/UIControls/Tab';
import Facilities from '~/Screens/Root/Facility/Common/Facilities';
import Accidents from '~/Screens/Root/Facility/Common/Accidents';
import Complaints from '~/Screens/Root/Facility/Common/Complaints';
import { Util } from '~/Utils/utils';
import { useAuth } from '~/Components/Hooks';
import { UploadFileType } from '~/Components/UIControls/UploadFile';
import { InputFilters } from '~/Components/UIControls/Input';

const titleWidth = 100;

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 workRequestId = navigation.getParam('workRequestId', 0);
    const workTypeId = navigation.getParam('workTypeId', 0);
    const tab = navigation.getParam('tab', 'info');
    const { auth, userinfo } = useAuth(navigation);

    const [loading, setLoading] = useState(false);
    const [data, setData] = useState({});
    const [facilities, setFacilities] = useState([]);
    const [accidents, setAccidents] = useState([]);
    const [complaints, setComplaints] = useState([]);
    const { prompt } = usePrompt();
    const { showMessage } = useToast();

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

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

        if(action != Form.CREATE) {
            try {
                const result = await fetchGet(`api/app/WorkRequest/Get?siteId=${siteId}&workRequestId=${workRequestId}`);
                setData(result);
                Form.setFormData(result);
                setFacilities(result.FmsWorkRequestToFacility);
                setAccidents(result.FmsWorkRequestToAccident);
                setComplaints(result.FmsWorkRequestToComplaint);
                setEditable(editable);
            } catch(error) {
                showMessage(error.message);
            }
        } else {
            const initialData = {
                WorkDetailType: {
                    Code: '',
                },
                StartWorkDate: new Date(),
                CmUserNavigation: {
                    Name: userinfo.Name
                },
            };
            setData(initialData);
            Form.setFormData(initialData);
        }

        setLoading(false);
    }

    // edit
    const onEdit = async () => {
        setFacilities(data.FmsWorkRequestToFacility);
        setAccidents(data.FmsWorkRequestToAccident);
        setComplaints(data.FmsWorkRequestToComplaint);
        setEditable(true);
    }

    // cancel edit
    const onCancelEdit = async () => {
        setFacilities(data.FmsWorkRequestToFacility);
        setAccidents(data.FmsWorkRequestToAccident);
        setComplaints(data.FmsWorkRequestToComplaint);
        setEditable(false);
    }

    // save
    const onSave = async form => {
        if(loading) {
            showMessage('처리중입니다. 잠시만기다려 주세요.');
            return;
        }
        confirm('저장', '저장하시겠습니까?', async () => {
            setLoading(true);
            const submit = {...form,
                SiteId: siteId,
                WorkTypeId: workTypeId,
                WorkRequestId: workRequestId,
                RequestUserId: userinfo.UserId,
                FmsWorkRequestToFacility: facilities,
                FmsWorkRequestToAccident: accidents,
                FmsWorkRequestToComplaint: complaints,
            };
            console.log('submit data', submit);

            try {
                const result = await fetchPost('api/app/WorkRequest/Save', submit);

                showMessage('저장되었습니다.');
                refreshList();
                if(action == Form.CREATE) {
                    navigation.pop();
                } else {
                    fetch(false);
                }
            } catch(error) {
                showMessage(error.message);
            }
            setLoading(false);
        });
    }

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

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

    return ( 
        <BottomTabBarLayout>
            <Fragment>
                <Tab>
                    <TabHeader>
                        <TabTitleGroup top={true}>
                            <TabTitle onPress={() => {
                                navigation.setParams({ tab: 'info' });
                            }} active={tab=='info'?true:false} title="공사작업계획" />
                            <TabTitle onPress={() => {
                                navigation.setParams({ tab: 'facilities' });
                            }} active={tab=='facilities'?true:false} title="시설목록" />
                            <TabTitle onPress={() => {
                                if(Util.get(data, "WorkDetailType.Code") == 'ACCIDENT') {
                                    navigation.setParams({ tab: 'accidents' });
                                }
                            }} active={tab=='accidents'?true:false} title="사고목록" />
                            <TabTitle onPress={() => {
                                if(Util.get(data, "WorkDetailType.Code") == 'COMPLAINT') {
                                    navigation.setParams({ tab: 'complaints' });
                                }
                            }} active={tab=='complaints'?true:false} title="민원목록" />
                        </TabTitleGroup>
                    </TabHeader>
                    <TabContent>
                        <TabItem active={tab=='info'?true:false}>
                            <Form.Container onSave={handleSubmit(onSave)} onDelete={onDelete} onEdit={onEdit} onCancelEdit={onCancelEdit}>
                                <Form.Field>
                                    <Form.Require style={{width:titleWidth}}><Form.Label>업무분야</Form.Label></Form.Require>
                                    <Form.EntitySelect entity="CmBusinessField" defaultLabel="업무분야"
                                                selectedValue={data.BusinessFieldId} selectedText={Util.get(data, "BusinessField.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} />

                                <Form.Field>
                                    <Form.Require style={{width:titleWidth}}><Form.Label>구분</Form.Label></Form.Require>
                                    <Form.EntitySelect entity="FmsWorkCodeDetailType" defaultLabel="구분"
                                                id="WorkDetailTypeId" name="Name" where={`WorkTypeId = ${workTypeId}`} fields="Code"
                                                selectedValue={data.WorkDetailTypeId} selectedText={Util.get(data, "WorkDetailType.Name")} editable={editable} useCheck={true}
                                                onChange={(item) => { 
                                                    setValue('WorkDetailTypeId', item.value, true);
                                                    Util.set(data, "WorkDetailType.Code", item.Code);
                                                }} />
                                </Form.Field>
                                <Form.Regist editable={editable} name="WorkDetailTypeId" rule={{required:'구분을 선택하세요.'}} error={errors.WorkDetailTypeId} />

                                <Form.Field>
                                    <Form.Title style={{width:titleWidth}}><Form.Label>신청자</Form.Label></Form.Title>
                                    <Form.Input defaultValue={Util.get(data, "CmUserNavigation.Name")} editable={false} />
                                </Form.Field>

                                <Form.Field>
                                    <Form.Require style={{width:titleWidth}}><Form.Label>신청제목</Form.Label></Form.Require>
                                    <Form.Input placeholder="신청제목" defaultValue={data.Title} 
                                                onChangeText={text => setValue('Title', text, true)} 
                                                editable={editable} returnKeyType="next" />
                                </Form.Field>
                                <Form.Regist editable={editable} name="Title" rule={{required:'신청제목을 입력하세요.'}} error={errors.Title} />

                                <Form.Field>
                                    <Form.Require style={{width:titleWidth}}><Form.Label>업무예정일</Form.Label></Form.Require>
                                    <Form.DatePicker date={data.StartWorkDate} minimumDate={Util.addMonth(-1)}
                                        onChange={(newDate) => setValue('StartWorkDate', newDate, true)} editable={editable} />
                                </Form.Field>
                                <Form.Regist editable={editable} name="StartWorkDate" rule={{required:'업무예정일을 선택하세요.'}} error={errors.StartWorkDate} />

                                <Form.Field>
                                    <Form.Require style={{width:titleWidth}}><Form.Label></Form.Label></Form.Require>
                                    <Form.DatePicker date={data.WorkEndDate} minimumDate={Util.addMonth(-1)}
                                        onChange={(newDate) => setValue('WorkEndDate', newDate, true)} editable={editable} />
                                </Form.Field>
                                <Form.Regist editable={editable} name="WorkEndDate" rule={{required:'업무예정일을 선택하세요.'}} error={errors.WorkEndDate} />

                                <Form.Field>
                                    <Form.Title style={{width:titleWidth}}><Form.Label>업체명</Form.Label></Form.Title>
                                    <Form.PopupSelect path="/Popup/Partner/Index" popupProps={{navigation, siteId}} 
                                        emptyLabel="업체" defaultLabel={data.WorkPartnerName} editable={editable}
                                        onSelect={(result) => {
                                            setValue('WorkPartnerId', result.PartnerId);
                                        }}
                                    />
                                </Form.Field>
                                <Form.Regist editable={editable} name="WorkPartnerId" />

                                <Form.Field>
                                    <Form.Title style={{width:titleWidth}}><Form.Label>금액</Form.Label></Form.Title>
                                    <Form.Input placeholder="금액" defaultValue={data.WorkPrice} 
                                                filter={text => {
                                                    return InputFilters.number(text);
                                                }}
                                                onChangeText={text => {
                                                    setValue('WorkPrice', text, true);
                                                }} 
                                                editable={editable} returnKeyType="next" />
                                </Form.Field>
                                <Form.Regist editable={editable} name="WorkPrice" />

                                <Form.Field>
                                    <Form.TitleTop style={{width:titleWidth}}><Form.Label>첨부파일</Form.Label></Form.TitleTop>
                                    <Form.UploadFile type={UploadFileType.Image} editable={editable} defaultFile={data.CmFile}
                                    onUpload={(isUpload, result) => {
                                        Form.uploadFile("CmFile", isUpload, result);
                                    }} onDelete={() => {
                                        Form.deleteFile("CmFile");
                                    }} />
                                </Form.Field>
                                <Form.RegistFile editable={editable} name="CmFile" value={data.CmFile} />

                                <Form.Field>
                                    <Form.TitleTop style={{width:titleWidth}}><Form.Label>내용</Form.Label></Form.TitleTop>
                                    <Form.Input placeholder="내용" defaultValue={data.Content} 
                                        onChangeText={text => setValue('Content', text, true)} 
                                        multiline={true} editable={editable} />
                                </Form.Field>
                                <Form.Regist editable={editable} name="Content" />

                                <Form.Field style={{ height:30 }}>
                                </Form.Field>
                            </Form.Container>
                        </TabItem>
                        <TabItem active={tab=='facilities'?true:false}>
                            <Facilities navigation={navigation} 
                                keys={{SiteId:siteId, WorkRequestId: workRequestId}}
                                facilities={facilities} setFacilities={setFacilities} editable={editable} />
                        </TabItem>
                        <TabItem active={tab=='accidents'?true:false}>
                            <Accidents navigation={navigation} 
                                keys={{SiteId:siteId, WorkRequestId: workRequestId}}
                                accidents={accidents} setAccidents={setAccidents} editable={(Util.get(data, "WorkDetailType.Code") == 'ACCIDENT' ? editable : false)} />
                        </TabItem>
                        <TabItem active={tab=='complaints'?true:false}>
                            <Complaints navigation={navigation} 
                                keys={{SiteId:siteId, WorkRequestId: workRequestId}}
                                complaints={complaints} setComplaints={setComplaints} editable={(Util.get(data, "WorkDetailType.Code") == 'COMPLAINT' ? editable : false)} />
                        </TabItem>
                    </TabContent>
                </Tab>
                {loading && <Form.Loading />}
            </Fragment>
        </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 navigation={navigation} />}
                        </Fragment>
                    )}
                    {editable && (
                        <Fragment>
                            {auth.Update && <Form.SaveButton type="primary" />}
                            {auth.Update && action != Form.CREATE && <Form.CancelEditButton navigation={navigation} />}
                        </Fragment>
                    )}
                    </Fragment>
                }
            /> 
        )
    } 
};

export default Screen;