import React, { Fragment, useState, useEffect, useLayoutEffect, useContext, useRef } from 'react';
import { ActivityIndicator } from 'react-native';
import session from '~/Utils/session';
import fetchGet, { 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 BottomTabBarLayout from '~/Components/Layouts/BottomTabBarLayout';
import { UploadFileType } from '~/Components/UIControls/UploadFile';
import { usePopup } from '~/Components/UIControls/Popup';
import { useAuth } from '~/Components/Hooks';
import { Selectbox } from '~/Components/UIControls/Selectbox';
import { Util } from '~/Utils/utils';
import { InputFilters } from '~/Components/UIControls/Input';
import { Tab, TabHeader, TabTitleGroup, TabTitle, TabContent, TabItem } from '~/Components/UIControls/Tab';
import MeteredList from './MeteredList';
import ReportList from './ReportList';
import moment from 'moment';

const getHours = () => {
    let hours = [];
    for(var i=0; i<24; i++) {
        hours.push({label:`${i}시`, value:i});
    }
    return hours;
}

const titleWidth = 100;

const Screen = ({navigation}) => {
    const { auth, userinfo } = useAuth(navigation);
    const editable = navigation.getParam('editable', auth.Update ? true : false);
    const refreshList = navigation.getParam('refreshList', ()=>{});
    const siteId = navigation.getParam('siteId', '');
    const facilityCode = navigation.getParam('facilityCode', 0);
    const propertyId = navigation.getParam('propertyId', 0);
    const tab = navigation.getParam('tab', 'manual-meter-form');
    const { showMessage } = useToast();

    const [loading, setLoading] = useState(false);
    const [data, setData] = useState({ });

    const [now, setNow] = useState(Util.toDateString());
    const hours = useRef(getHours());

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

    // 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();

        try {
            let result = await fetchGet(`api/app/ManualMeter/Get?siteId=${siteId}&facilityCode=${facilityCode}&propertyId=${propertyId}&date=${now}`);
            let obj = {
                ...result.Item,
                ...result.Expansion
            }
            if(obj.PrevPinValue === 0) obj.PrevPinValue = '';
            if(obj.CurrentPinValue === 0) obj.CurrentPinValue = '';
            if(obj.CurrentValue == 0) obj.CurrentValue = '0';
            obj.EditablePrevPinValue = !obj.PrevPinValue;
            console.log(obj);
            setData(obj);
            Form.setFormData(obj);
        } catch(error) {
            showMessage(error.message);
        }

        setLoading(false);
    }

    const fetchCurrentValue = async (date, hour) => {
        setLoading(true);
        await session.load();

        try {
            let mv = moment(date);
            mv.hour(hour);
            const hourDateTime = mv.format('YYYY-MM-DD HH:mm:ss');
            let result = await fetchGet(`api/app/ManualMeter/GetCurrentValue?siteId=${siteId}&facilityCode=${facilityCode}&propertyId=${propertyId}&date=${hourDateTime}`);
            if(result.PrevPinValue === 0) result.PrevPinValue = '';
            if(result.CurrentPinValue === 0) result.CurrentPinValue = '';
            if(result.CurrentValue == 0) result.CurrentValue = '0';
            result.EditablePrevPinValue = !result.PrevPinValue;
            console.log(result);
            setData({...data, ...result});
            Form.setFormData({...data, ...result});
        } catch(error) {
            console.log(error);
            showMessage(error.message);
        }

        setLoading(false);
    }

    const fetchLastMeteredHour = async (date) => {
        try {
            let mv = moment(date);
            if(!mv.isValid()) {
                showMessage('입력된 날짜 형식이 잘못되었습니다.');
                return null;
            }
            const dateString = mv.format('YYYY-MM-DD');
            let result = await fetchGet(`api/app/ManualMeter/GetLastMeteredHour?siteId=${siteId}&facilityCode=${facilityCode}&propertyId=${propertyId}&date=${dateString}`);
            return result.Hour;
        } catch(error) {
            console.log(error);
            showMessage(error.message);
        }

        return null;
    }

    // save
    const onSave = async form => {
        if(loading) {
            showMessage('저장중입니다. 잠시만기다려 주세요.');
            return;
        }
        confirm('저장', '저장하시겠습니까?', async () => {
            setLoading(true);
            const submit = {...form,
                SiteId: siteId,
                FacilityCode: facilityCode,
                PropertyId: propertyId,
                CreatedDateTime: now + ` ${form.Hour}:00:00`,
            };
            console.log('submit data', submit);
            if(data.CurrentValue >= 0){
                try {
                    const result = await fetchPost('api/app/ManualMeter/Save', submit);

                    showMessage('저장되었습니다.');
                    refreshList();
                    fetchCurrentValue(now, data.Hour);
                } catch(error) {
                    showMessage(error.message);
                }
            }else{
                showMessage('검침값이 이전 검침값보다 작습니다.');
            }
            setLoading(false);
        });
    }

    const calcCurrentValue = (currentPinValue, prevPinValue, multiple) => {
        return Math.round((currentPinValue - prevPinValue) * multiple * 100) / 100;
    }

    return ( 
        <BottomTabBarLayout>
            <Tab>
                <TabHeader>
                    <TabTitleGroup top={true}>
                        <TabTitle onPress={() => {
                            navigation.setParams({ tab: 'manual-meter-form' });
                        }} active={tab=='manual-meter-form'?true:false} title="에너지검침등록" />
                        <TabTitle onPress={() => {
                            navigation.setParams({ tab: 'manual-meter-list' });
                        }} active={tab=='manual-meter-list'?true:false} title="검침목록" />
                        <TabTitle onPress={() => {
                            navigation.setParams({ tab: 'daily-report-list' });
                        }} active={tab=='daily-report-list'?true:false} title="일지목록" />
                    </TabTitleGroup>
                </TabHeader>
                <TabContent>
                    <TabItem active={tab=='manual-meter-form'?true:false}>
                        <Form.Container onSave={handleSubmit(onSave)} loading={loading}>
                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>검침일자</Form.Label></Form.Title>
                                <Form.DatePicker date={now} onChange={(newDate) => { 
                                    setNow(newDate);
                                    if(moment(newDate).isBefore(moment(), 'day')) {
                                        (async () => {
                                            let hour = await fetchLastMeteredHour(newDate);
                                            if(!hour) hour = data.Hour;
                                            setValue('Hour', hour, true);
                                            setData({...data, Hour: hour });
                                            fetchCurrentValue(newDate, hour);
                                        })();
                                    } else {
                                        fetchCurrentValue(newDate, data.Hour);
                                    }
                                }} editable={editable} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Require style={{width:titleWidth}}><Form.Label>검침시간</Form.Label></Form.Require>
                                <Selectbox style={{flex:1}} defaultLabel="검침시간" emptyLabel="전체" editable={editable}
                                    items={hours.current} selectedValue={data.Hour} onChange={item => {
                                        setValue('Hour', item.value, true);
                                        setData({...data, Hour:item.value });
                                        fetchCurrentValue(now, item.value);
                                    }} />
                            </Form.Field>
                            <Form.Regist editable={editable} name="Hour" rule={{required:'검침시간을 선택하세요.'}} error={errors.Hour} />

                            <Form.Field>
                                <Form.Require style={{width:titleWidth}}><Form.Label>이전검침값</Form.Label></Form.Require>
                                <Form.Input 
                                    editable={data.EditablePrevPinValue} 
                                    value={data.PrevPinValue} 
                                    defaultValue={data.PrevPinValue}
                                    onChangeText={(text) => {
                                        const currentValue = data.CurrentPinValue == '' ? '0' : calcCurrentValue(data.CurrentPinValue, Util.parseFloat(text), data.Multiple);
                                        setValue('PrevPinValue', text, true);
                                        setValue('CurrentValue', currentValue, true);
                                        setData({...data, PrevPinValue: text, CurrentValue: currentValue});
                                    }} 
                                    keyboardType="decimal-pad" 
                                />
                            </Form.Field>
                            <Form.Regist editable={editable} name="PrevPinValue" rule={{
                                required: '이전검침값을 입력하세요.',
                                pattern: {
                                    value: /^[0-9]+[\.]?[0-9]*$/,
                                    message: '이전검침값은 숫자만 입력 가능합니다.',
                                }
                            }} error={errors.PrevPinValue} />

                            <Form.Field>
                                <Form.Require style={{width:titleWidth}}><Form.Label>검침값</Form.Label></Form.Require>
                                <Form.Input 
                                    editable={editable} 
                                    value={data.CurrentPinValue} 
                                    onChangeText={(text) => {
                                        const currentValue = text == '' ? '0' : calcCurrentValue(Util.parseFloat(text), data.PrevPinValue, data.Multiple);
                                        setValue('CurrentPinValue', text, true);
                                        setValue('CurrentValue', currentValue, true);
                                        setData({...data, CurrentPinValue:text,CurrentValue:currentValue});
                                    }} 
                                    keyboardType="decimal-pad" 
                                />
                            </Form.Field>
                            <Form.Regist editable={editable} name="CurrentPinValue" rule={{
                                required: '검침값을 입력하세요.',
                                pattern: {
                                    value: /^[0-9]+[\.]?[0-9]*$/,
                                    message: '검침값은 숫자만 입력 가능합니다.',
                                }
                            }} error={errors.CurrentPinValue} />

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>배수</Form.Label></Form.Title>
                                <Form.Input editable={false} value={data.Multiple} keyboardType="decimal-pad" />
                            </Form.Field>
                            <Form.Regist editable={editable} name="Multiple" error={errors.Multiple} />

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>사용량</Form.Label></Form.Title>
                                <Form.Input editable={false} value={data.CurrentValue} keyboardType="decimal-pad" />
                            </Form.Field>
                            <Form.Regist editable={editable} name="CurrentValue"  error={errors.CurrentValue} />

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>시설명칭</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.Name} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>시설별칭</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.Nickname} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>시설유형</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.FacilityTypeName} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>설치위치</Form.Label></Form.Title>
                                <Form.Input defaultValue={`${Util.get(data, "BuildingName", '')} > ${Util.get(data, "FloorName", '')} > ${Util.get(data, "ZoneName", '')}`} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>시설분류</Form.Label></Form.Title>
                                <Form.Input defaultValue={`${Util.get(data, "FirstClassName", '')} > ${Util.get(data, "SecondClassName", '')} > ${Util.get(data, "ThirdClassName", '')}`} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>제조업체</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.Manufacturer} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>시설용량</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.FacilityCapacity} editable={false} />
                            </Form.Field>

                            <Form.Field>
                                <Form.Title style={{width:titleWidth}}><Form.Label>QR코드</Form.Label></Form.Title>
                                <Form.Input defaultValue={data.Rfid} editable={false} />
                            </Form.Field>

                            <Form.Field style={{ height:30 }}>
                            </Form.Field>
                        </Form.Container>
                    </TabItem>

                    <TabItem active={tab=='manual-meter-list'?true:false} lazy={true} alwaysReload={true}>
                        <MeteredList navigation={navigation} siteId={siteId} facilityCode={facilityCode} propertyId={propertyId} date={now} />
                    </TabItem>

                    <TabItem active={tab=='daily-report-list'?true:false} lazy={true} alwaysReload={true}>
                        <ReportList navigation={navigation} siteId={siteId} facilityCode={facilityCode} propertyId={propertyId} date={now} />
                    </TabItem>
                </TabContent>
            </Tab>

        </BottomTabBarLayout>
    );
};

Screen.navigationOptions = ({navigation}) => { 
    const { auth, userinfo } = useAuth(navigation);
    const tab = navigation.getParam('tab', 'manual-meter-form');

    return { 
        header: () => (
            <Header 
                navigation={navigation} 
                title={`에너지 수검침`}
                main={false}
                buttons={
                    <Fragment>
                        {auth.Update && tab == 'manual-meter-form' && (<Form.SaveButton type="primary" />)}
                    </Fragment>
                }
            /> 
        )
    } 
};

export default Screen;